为什么使用Redux而不是Facebook Flux?

VB_*_*VB_ 1126 javascript flux reactjs reactjs-flux redux

我已经阅读了这个答案,减少了样板,看了几个GitHub示例,甚至尝试了redux(todo apps).

据我了解,官方redux doc动机提供了与传统MVC架构相比的优点.但它没有提供问题的答案:

为什么你应该使用Redux而不是Facebook Flux?

这只是编程风格的问题:功能与非功能?或者问题是在redux方法中遵循的能力/开发工具?也许缩放?还是测试?

如果我说redux对于来自函数式语言的人来说是一种变化,我是对的吗?

要回答这个问题,您可以比较实施redux在flux和redux上的动机点的复杂性.

以下是官方redux doc动机的动机点:

  1. 处理乐观的更新(据我所知,它几乎不取决于第5点.难道在facebook flux中实现它吗?)
  2. 在服务器上渲染(facebook flux也可以做到这一点.与redux相比有什么好处?)
  3. 在执行路由转换之前获取数据(为什么在facebook中无法实现?有什么好处?)
  4. 热重载(可以使用React Hot Reload.为什么我们需要redux?)
  5. 撤消/重做功能
  6. 还有其他一点吗?像坚持国家一样......

Dan*_*mov 1958

Redux的作者在这里!

Redux 与Flux 没有什么不同.总体而言,它具有相同的架构,但Redux能够通过使用Flux使用回调注册的功能组合来削减一些复杂角落.

Redux没有根本的区别,但是我发现它使得某些抽象更容易,或者至少可以实现,这在Flux中很难或不可能实现.

减速剂成分

以分页为例.My Flux + React Router示例处理分页,但代码很糟糕.可怕的原因之一是Flux使得跨商店重用功能变得不自然.如果两个商店需要处理分页以响应不同的操作,它们或者需要从公共基本存储继承(糟糕!当您使用继承时将自己锁定到特定设计中),或者从内部调用外部定义的函数事件处理程序,需要以某种方式操作Flux存储的私有状态.整件事情很混乱(虽然绝对是可能的).

另一方面,由于减速器的成分,Redux的分页很自然.它一直是减速器,因此您可以编写一个减速器工厂来生成分页减速器,然后在减速器树中使用它.这么简单的关键是因为在Flux中,商店是平的,但在Redux中,Reducer可以通过功能组合嵌套,就像React组件可以嵌套一样.

此模式还支持非用户代码撤消/重做等精彩功能.你能想象将Undo/Redo插入一个两行代码的Flux应用程序吗?几乎不.使用Redux,由于减速器组成模式,它是重要的.我需要强调的是,没有什么新鲜事 - 这是Elm Architecture中开创并详细描述的模式,它本身受到Flux的影响.

服务器渲染

人们使用Flux在服务器上渲染得很好,但是看到我们有20个Flux库,每个都试图让服务器呈现"更容易",也许Flux在服务器上有一些粗糙的边缘.事实是Facebook没有做太多的服务器渲染,所以他们并没有非常关注它,并依靠生态系统来使它更容易.

在传统的Flux中,商店是单身人士.这意味着很难为服务器上的不同请求分离数据.不是不可能,但很难.这就是为什么大多数Flux库(以及新的Flux Utils)现在建议您使用类而不是单例,因此您可以按请求实例化存储.

您仍需要在Flux中解决以下问题(您自己或在您喜欢的Flux库(如FlummoxAlt)的帮助下):

  • 如果商店是类,我如何使用每个请求的调度程序创建和销毁它们?我什么时候注册商店?
  • 如何保存商店中的数据,然后在客户端上重新水合?我需要为此实现特殊方法吗?

不可否认,Flux框架(不是vanilla Flux)可以解决这些问题,但我发现它们过于复杂.例如,惊讶问你来实现serialize(),并deserialize()在你的商店.Alt通过提供takeSnapshot()自动序列化JSON树中的状态来解决这个问题.

Redux更进一步:因为只有一个商店(由许多减速器管理),你不需要任何特殊的API来管理(重新)水合作用.您不需要"刷新"或"保湿"商店 - 只有一个商店,您可以读取其当前状态,或创建具有新状态的新商店.每个请求都有一个单独的商店实例.阅读有关Redux服务器渲染的更多信息.

同样,这是Flux和Redux中可能存在的一种情况,但是Flux库通过引入大量API和约定来解决这个问题,而Redux甚至不必解决它,因为它没有解决这个问题.第一名归功于概念简洁.

开发经验

我实际上并没有打算让Redux成为一个受欢迎的Flux库 - 我写的是因为我正在研究ReactEurope关于时间旅行热重载的讨论.我有一个主要目标:可以动态更改减速器代码,甚至可以通过交叉操作"改变过去",并查看重新计算的状态.

我还没有看到一个能够做到这一点的Flux库.React Hot Loader也不允许你这样做 - 事实上,如果你编辑Flux商店它会中断,因为它不知道如何处理它们.

当Redux需要重新加载reducer代码时,它会调用replaceReducer(),并且应用程序将使用新代码运行.在Flux中,数据和功能纠缠在Flux存储中,因此您不能"只更换功能".此外,您必须以某种方式使用Dispatcher重新注册新版本 - Redux甚至没有.

生态系统

Redux拥有丰富且快速发展的生态系统.这是因为它提供了一些扩展点,如中间件.它的设计考虑了日志,支持Promises,Observables,路由,immutability dev检查,持久性等用例.并非所有这些都会变得有用,但是访问一组可以轻松组合在一起工作的工具是很好的.

简单

Redux保留了Flux的所有优点(记录和重放动作,单向数据流,依赖变异)并增加了新的好处(简单的撤销重做,热重新加载),而不引入Dispatcher和商店注册.

保持简单很重要,因为它可以在您实现更高级别的抽象时保持理智.

与大多数Flux库不同,Redux API表面很小.如果删除开发人员警告,注释和完整性检查,则为99行.调试没有棘手的异步代码.

您实际上可以阅读它并了解Redux的所有内容.


另请参阅我对使用Redux与Flux相比的缺点的答案.

  • 你想学习Redux吗?请观看此视频:https://www.youtube.com/watch?v = cuc5x3Ka3gw (5认同)
  • 我们之所以选择redux,是因为它比通量更具有说服力.我们一直在争论某些代码应该如何/在哪里等等.Redux为我们消除了所有这些混乱.我们已经构建了带有redux for web和react-native的应用程序,这太棒了! (5认同)
  • 谢谢你的回答...我是js的新手......在你的回答中你说焊剂使用的是单件设计模式......你能告诉我他们正在使用什么样的设计模式......并且在焊剂中可以你告诉我他们在哪里使用单件模式...你能给出一个例子......我从这里了解设计模式是什么[singleton](http://www.dofactory.com/javascript/singleton-design-pattern ) (3认同)
  • 我基于Fluxxor开始了我的Android/Java实现(Fluxxan)(基本上是纯粹的通量).一旦我看到redux,我就卖了.有些部分我保持纯粹的流量,但是男人,你的lib很棒! (2认同)

Ali*_*eza 101

在Quora,有人说:

首先,完全可以使用React编写应用程序而不使用Flux.

此外,我创建的这个视觉图表显示了两者的快速视图,可能是一个快速的答案,不想阅读整个解释的人: Flux vs Redux

但如果您仍然对更多信息感兴趣,请继续阅读.

我相信你应该从纯粹的React开始,然后学习Redux和Flux.在您对React有一些实际经验之后,您将看到Redux是否对您有所帮助.

也许你会觉得Redux完全适合你的应用程序,也许你会发现,Redux正试图解决你并没有真正遇到的问题.

如果你直接使用Redux,你最终可能会得到过度设计的代码,代码难以维护,甚至更多的错误,而不是没有Redux.

来自Redux文档:

动机
随着JavaScript单页面应用程序的需求变得越来越复杂,我们的代码必须管理比以往更多的状态.此状态可以包括服务器响应和缓存数据,以及尚未持久保存到服务器的本地创建的数据.UI状态的复杂性也在增加,因为我们需要管理活动路径,选定选项卡,微调器,分页控件等.

管理这个不断变化的状态很难.如果模型可以更新另一个模型,则视图可以更新模型,该模型会更新另一个模型,而这反过来可能会导致另一个视图更新.在某些时候,您不再理解您的应用中发生了什么,因为您已经失去了对其状态的时间,原因和方式的控制.当系统不透明且不确定时,很难重现错误或添加新功能.

好像这还不够糟糕,考虑新要求在前端产品开发中变得普遍.作为开发人员,我们期望处理乐观更新,服务器端呈现,在执行路由转换之前获取数据等等.我们发现自己试图管理以前从未处理过的复杂性,我们不可避免地提出这样一个问题:是时候放弃了吗?答案是不.

这种复杂性很难处理,因为我们混合了人类思维难以推理的两个概念:变异和异步性.我称他们为Mentos和Coke.两者在分离时都很棒,但它们一起造成混乱.像React这样的库试图通过删除异步和直接DOM操作来解决视图层中的这个问题.但是,管理数据状态取决于您.这是Redux的用武之地.

跟随Flux,CQRS和Event Sourcing的脚步,Redux试图通过对更新发生的方式和时间施加某些限制来使状态突变可预测.这些限制反映在Redux的三个原则中.

也来自Redux docs:

核心概念
Redux本身非常简单.

想象一下,您的应用程序的状态被描述为一个普通对象.例如,todo应用程序的状态可能如下所示:

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}
Run Code Online (Sandbox Code Playgroud)

这个对象就像一个"模型",除了没有setter.这样代码的不同部分不能任意改变状态,导致难以重现的错误.

要更改状态中的某些内容,您需要发送操作.一个动作是一个简单的JavaScript对象(请注意我们如何不引入任何魔法?)来描述发生了什么.以下是一些示例操作:

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
Run Code Online (Sandbox Code Playgroud)

强制将每个更改描述为一个操作,让我们清楚地了解应用程序中发生的情况.如果发生了变化,我们就知道它为什么会改变 行动就像发生了什么的面包屑.最后,为了将状态和动作联系在一起,我们编写了一个名为reducer的函数.再一次,它没有什么神奇之处 - 它只是一个将状态和动作作为参数的函数,并返回应用程序的下一个状态.为大型应用程序编写这样的函数会很困难,所以我们编写管理状态部分的较小函数:

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}
Run Code Online (Sandbox Code Playgroud)

我们编写另一个reducer来管理应用程序的完整状态,方法是调用相应状态键的两个reducers:

function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  };
}
Run Code Online (Sandbox Code Playgroud)

这基本上是Redux的整个想法.请注意,我们没有使用任何Redux API.它附带了一些实用程序来促进这种模式,但主要的想法是描述你的状态如何随着时间的推移而更新以响应操作对象,并且你编写的90%的代码只是简单的JavaScript,没有使用Redux本身,它的API,或任何魔术.


Hal*_*Hal 57

你可能最好开始阅读Dan Abramov的这篇文章,他在撰写redux时讨论了Flux的各种实现及其权衡: Flux框架的演变

其次,你链接的动机页面并没有真正讨论Redux的动机,而是Flux(和React)背后的动机.该三原则是更终极版特定但仍无法应付来自标准通量架构的实现差异.

基本上,Flux有多个商店,可以响应UI/API与组件的交互来计算状态变化,并将这些更改作为组件可以订阅的事件进行广播.在Redux中,每个组件只有一个商店订阅.IMO感觉至少像Redux通过统一(或减少,如Redux所说)数据流回到组件来进一步简化和统一数据流 - 而Flux专注于统一数据流的另一面 - 查看到模型.


Guy*_*her 27

我是早期采用者,使用Facebook Flux库实现了一个中大型单页面应用程序.

由于我对谈话有点迟,我只想指出,尽管我最好的希望Facebook似乎认为他们的Flux实现是一个概念证明,它从未得到应有的关注.

我鼓励你玩它,因为它暴露了Flux架构的更多内部工作,这是非常有教育意义的,但同时它没有提供像Redux这样的库提供的许​​多好处(它们不是这对小型项目很重要,但对大型项目非常有价值).

我们决定继续前进,我们将转向Redux,我建议你这样做;)


Pra*_*upu 20

以下是Redux over Flux的简单解释.Redux没有调度程序.它依赖于名为reducers的纯函数.它不需要调度员.每个操作由一个或多个Reducer处理以更新单个存储.由于数据是不可变的,因此reducers返回更新存储的新更新状态在此输入图像描述

有关更多信息,请访问http://www.prathapkudupublog.com/2017/04/flux-vs-redux.html


Kra*_*mir 6

我在Flux工作了很长时间,现在在Redux中工作了很长时间。正如Dan所指出的,两种架构都没有太大不同。事实是Redux使事情变得更简单,更清洁。它教会了您有关Flux的一些知识。例如,Flux是单向数据流的完美示例。关注点分离在我们拥有数据的地方,其操作和视图层是分离的。在Redux中,我们有相同的东西,但我们还了解了不变性和纯函数。


Aci*_*ier 5

来自一个新的react / redux采用者,它是在2018年中期从ExtJS(几年)迁移而来的:

向后滑下redux学习曲线后,我遇到了相同的问题,并认为纯通量像OP一样简单。

我很快看到了redux相对于通量的好处,如上面的答案所述,并且正在将其用于我的第一个应用程序。

在再次掌握样板时,我尝试了一些其他状态管理库,发现的最好是rematch

vanilla redux直观得多,它减少了90%的样板,减少了我花在redux上的时间的75%(我认为是图书馆应该做的事情),我能够得到一些企业应用程序马上去。

它还使用相同的redux工具运行。这是一篇很好的文章,涵盖了一些好处。

因此,对于到达此SO职位搜索“更简单的redux”的任何人,我建议尝试使用它作为redux的一种简单替代方法,它具有所有优势和1/4的样板。