我读过this answer,reducing boilerplate,看了几个GitHub的例子,甚至试了一下redux(todo apps) .
据我了解,official redux doc motivations提供了与传统MVC架构相比的优点 . 但它没有提供问题的答案:
Why you should use Redux over Facebook Flux?
这只是编程风格的问题:功能与非功能?或者问题是在redux方法中遵循的能力/开发工具?也许缩放?还是测试?
如果我说redux对于来自函数式语言的人来说是一种变化,我是对的吗?
To answer this question you may compare the complexity of implementation redux's motivation points on flux vs redux.
以下是official redux doc motivations的动机要点:
-
处理乐观更新(据我所知,它几乎不取决于第5点 . 难道在facebook flux中实现它吗?)
-
在服务器上渲染(facebook flux也可以这样做 . 与redux相比有什么好处?)
-
在执行路由转换之前获取数据(为什么它可以't be achieved in facebook flux? What'的好处?)
-
热重装(这可能是React Hot Reload . 为什么我们需要redux?)
-
撤消/重做功能
-
其他什么点?像坚持国家一样......
8 回答
以下是Redux over Flux的简单解释 . Redux没有调度程序 . 它依赖于名为reducers的纯函数 . 它不需要调度员 . 每个操作由一个或多个Reducer处理以更新单个存储 . 由于数据是不可变的,因此reducers返回更新存储的新更新状态
有关更多信息http://www.prathapkudupublog.com/2017/04/flux-vs-redux.html
我是早期采用者,使用Facebook Flux库实现了一个中大型单页面应用程序 .
由于我的谈话有点迟,我只想指出,尽管我最好的希望Facebook似乎认为他们的Flux实施是一个概念证明,它从未得到应有的关注 .
我鼓励你玩它,因为它暴露了Flux架构的更多内部工作,这是非常有教育意义,但同时它没有提供像Redux这样的库提供的许多好处(它们不是这对小型项目很重要,但对大型项目非常有 Value ) .
我们决定继续前进,我们将转向Redux,我建议你这样做;)
Redux作者在这里!
Redux与Flux没有什么不同 . 总体而言,它具有相同的架构,但Redux能够通过使用Flux使用回调注册的功能组合来削减一些复杂角落 .
Redux没有根本的区别,但是我发现它使得某些抽象更容易,或者至少可以实现,这在Flux中很难或不可能实现 .
减速剂成分
以分页为例 . 我的Flux + React Router example处理分页,但代码很糟糕 . 可怕的原因之一是 Flux makes it unnatural to reuse functionality across stores. 如果两个商店需要处理分页以响应不同的操作,他们要么需要从公共基础商店继承(糟糕!你是私有状态 . 整个事情是混乱的(虽然肯定在可能的领域) .
另一方面,由于减速器的成分,Redux的分页很自然 . 它一直是减速器,所以你可以写一个reducer factory that generates pagination reducers然后use it in your reducer tree . 这么简单的关键因为 in Flux, stores are flat, but in Redux, reducers can be nested via functional composition, just like React components can be nested.
这种模式还可以实现非用户代码undo/redo等精彩功能 . Can you imagine plugging Undo/Redo into a Flux app being two lines of code? Hardly. With Redux, it is -感谢减速器组成模式 . 我需要强调的是,它并没有什么新鲜事 - 这是在_153179中开创并详细描述的模式,它本身受到Flux的影响 .
服务器渲染
人们使用Flux在服务器上渲染得很好,但是看到我们有20个Flux库,每个都试图让服务器呈现“更容易”,也许Flux在服务器上有一些粗糙的边缘 . 事实是Facebook没有做太多的服务器渲染,因此他们并没有非常关注它,而是依靠生态系统来简化它 .
在传统的Flux中,商店是单身人士 . 这意味着很难为服务器上的不同请求分离数据 . 不是不可能,但很难 . 这就是为什么大多数Flux库(以及新的Flux Utils)现在建议您使用类而不是单例,因此您可以为每个请求实例化存储 .
您需要在Flux中解决以下问题(您自己或在您喜欢的Flux库的帮助下,例如Flummox或Alt):
如果商店是类,我如何使用每个请求的调度程序创建和销毁它们?我什么时候注册商店?
如何保存商店中的数据,然后在客户端进行补水?我需要为此实现特殊方法吗?
诚然,Flux框架(不是vanilla Flux)可以解决这些问题,但我发现它们过于复杂 . 例如,Flummox asks you to implement serialize() and deserialize() in your stores . Alt通过提供takeSnapshot()来自动序列化JSON树中的状态,从而解决了这个问题 .
Redux更进一步: since there is just a single store (managed by many reducers), you don't need any special API to manage the (re)hydration. 你只是一个商店,你可以读取其当前状态,或创建具有新状态的新商店 . 每个请求都有一个单独的商店实例 . Read more about server rendering with Redux.
同样,这是一个可能在Flux和Redux中都有可能的情况,但是Flux库通过引入大量的API和约定来解决这个问题,而Redux甚至不需要解决它,因为它没有解决这个问题 . 首先归功于概念简洁性 .
开发人员体验
我实际上并不打算让Redux成为一个受欢迎的Flux库 - 我在写作ReactEurope talk on hot reloading with time travel时写了它 . 我有一个主要目标: make it possible to change reducer code on the fly or even “change the past” by crossing out actions, and see the state being recalculated.
我还没有看到一个能够做到这一点的Flux库 . React Hot Loader也不允许你这样做 - 事实上,如果你编辑Flux商店它会中断,因为它不知道如何处理它们 .
当Redux需要重新加载reducer代码时,它会调用replaceReducer(),并且应用程序将使用新代码运行 . 在Flux中,数据和函数纠缠在Flux存储中,因此您必须以某种方式使用Dispatcher重新注册新版本 - Redux甚至没有 .
生态系统
Redux有rich and fast-growing ecosystem . 这是因为它提供了一些扩展点,例如middleware . 它的设计考虑了logging,支持Promises,Observables,routing,immutability dev checks,persistence等用例 . 并非所有这些都会变得有用,但很高兴能够访问一组可以轻松组合在一起工作的工具 .
简洁
Redux保留了Flux的所有优点(记录和重放动作,单向数据流,依赖变异),并增加了新的好处(轻松撤消 - 重做,热重新加载),而无需引入Dispatcher和商店注册 .
保持简单很重要,因为它可以在您实现更高级别的抽象时保持理智 .
与大多数Flux库不同,Redux API表面很小 . 如果删除开发人员警告,注释和完整性检查,则为99 lines . 调试没有棘手的异步代码 .
您实际上可以阅读它并了解Redux的所有内容 .
另见my answer on downsides of using Redux compared to Flux .
我在Flux工作了很长时间,现在使用Redux已经很长时间了 . 正如丹指出的那样,两种架构都没有那么不同 . 事情是,Redux使事情更简单,更清洁 . 它会在Flux上教你一些东西 . 例如,Flux是单向数据流的完美示例 . 我们将数据,操作和视图层分开的问题分离 . 在Redux中我们有相同的东西,但我们也学习了不变性和纯函数 .
In Quora, somebody says:
也是这个 visual diagram ,我想阅读整个解释:
但如果您仍然对更多信息感兴趣,请继续阅读 .
从Redux docs:
同样来自Redux docs:
function todos(state = [],action){
switch(action.type){
案例'ADD_TODO':
return state.concat([{text:action.text,completed:false}]);
案例'TOGGLE_TODO':
return state.map((todo,index)=>
action.index === index?
{text:todo.text,completed:!todo.completed}:
去做
)
默认:
返回状态;
}
}
我们编写另一个reducer来管理应用程序的完整状态,方法是调用相应状态键的两个reducers:function todoApp(state = {},action){
返回{
todos:todos(state.todos,action),
visibilityFilter:visibilityFilter(state.visibilityFilter,action)
};
}
这基本上是Redux的整个想法 . 请注意,我们没有使用任何Redux API . 它附带了一些实用程序来实现这种模式,但主要的想法是描述状态如何随着时间的推移而更新以响应操作对象,并且您编写的90%的代码只是简单的JavaScript,没有使用Redux本身,它的API,或任何魔术 .
你可能最好开始阅读Dan Abramov的这篇文章,他在撰写redux时讨论了Flux的各种实现及其权衡:The Evolution of Flux Frameworks
其次,你链接的动机页面并没有真正讨论Redux的动机,而是Flux(和React)背后的动机 . Three Principles更具特定于Redux,但仍然没有处理与标准Flux架构的实现差异 .
基本上,Flux有多个商店,可以响应UI / API与组件的交互来计算状态变化,并将这些变化作为组件可以订阅的事件进行广播 . 在Redux中,每个组件只有一个商店订阅 . IMO感觉至少像Redux通过统一(或减少,如Redux所说)数据流回到组件来进一步简化和统一数据流 - 而Flux专注于统一数据流的另一端 - 查看到模型 .
除了前面答案中描述的技术论点,恕我直言的两个重要原因是:
工具:Redux开发工具是一个很棒的工具,让您的开发人员/调试体验充满活力(时间机器,导出用户会话并在本地环境中重放它的能力......) .
堆栈溢出友好:Redux在stackoverflow上获得超过51000个结果,通量9000 .
来自2018年中期从(几年)ExtJS迁移的新的react / redux采用者:
在向下滑动redux学习曲线后,我有同样的问题,并认为纯通量会像OP一样简单 .
我很快就看到了如上面的答案中所提到的还原剂的优势,并且正在将其应用到我的第一个应用程序中 .
在再次 grab 锅炉板的同时,我尝试了一些其他的状态管理库,我找到的最好的是rematch .
它比香草还原更直观,它削减了90%的样板,减少了我花在redux上的75%(我认为库应该做的事情),我能够得到几个企业应用程序马上去 .
它也使用相同的redux工具运行 . 这是good article这涵盖了一些好处 .
因此,对于那些到达此SO帖子搜索“更简单的redux”的人,我建议尝试将其作为redux的一个简单替代方案,具有所有优点和四分之一的样板 .