Redux作者在这里!
Redux和Flux没有什么不同.总的来说,它具有相同的体系 struct ,但Redux能够通过使用函数组合(Flux使用回调注册)来减少一些复杂性.
Redux没有本质上的区别,但我发现它使某些抽象变得更容易,或者至少可以实现,而这些抽象在Flux中是很难实现的,或者是不可能实现的.
还原剂成分
以分页为例.我的Flux + React Router example处理分页,但是代码很糟糕.糟糕的原因之一是,Flux makes it unnatural to reuse functionality across stores.如果两个存储需要处理分页以响应不同的操作,则它们要么需要从公共基础存储继承(坏!当您使用继承时,您会将自己锁定在特定的设计中),或者从事件处理程序中调用外部定义的函数,这将需要以某种方式操作Flux存储的私有状态.整个事情一团糟(尽管绝对在可能的范围内).
另一方面,使用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再次感谢减速器组成模式.我需要强调的是,这并不是什么 fresh 事,这是在Elm Architecture中开创并详细描述的模式,它本身受流量的影响.
服务器渲染
人们一直在使用Flux在服务器上渲染,但是看到我们有20个Flux库,每个库都试图使服务器渲染"更容易",也许Flux在服务器上有一些粗糙的边缘.事实是,Facebook没有做太多的服务器渲染,所以他们并不是很关心它,而是依靠生态系统让它变得更容易.
在传统的Flux中,store 是单件的.这意味着很难将服务器上不同请求的数据分开.不是不可能,但很难.这就是为什么大多数Flux库(以及新的Flux Utils)现在建议您使用类而不是单例,这样您就可以按请求实例化存储.
在Flux中,您仍然需要解决以下问题(您自己或借助您最喜欢的Flux库,如Flummox或Alt):
- 如果存储是类,我如何使用Dispatcher per Request创建和销毁它们?我什么时候注册store ?
- 如何将存储区中的数据水合,然后在客户机上重新水合?我需要为此实施特殊方法吗?
诚然,Flux框架(不是普通的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.你不需要"刷新"或"加水"store --只有一个store ,你可以读取它的当前状态,或者用新的状态创建一个新的store .每个请求都有一个单独的存储实例.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需要重新加载减速器代码时,它会调用replaceReducer()
,应用程序就会使用新代码运行.在Flux中,数据和函数在Flux存储中纠缠在一起,因此您不能"简单地替换函数".此外,您还必须以某种方式向调度程序重新注册新版本-这是Redux甚至没有的.
生态系统
Redux有一个rich and fast-growing ecosystem.这是因为它提供了一些扩展点,比如middleware.它的设计考虑了logging、Promises、Observables、routing、immutability dev checks、persistence等用例.并不是所有这些都会有用,但有机会使用一套可以轻松组合在一起工作的工具是很好的.
简单
Redux保留了Flux的所有好处(动作的记录和重放、单向数据流、依赖性Mutations ),并在不引入Dispatcher和store注册的情况下增加了新的好处(轻松撤销重做、热重新加载).
保持它的简单是很重要的,因为当你实现更高层次的抽象时,它可以让你保持理智.
与大多数通量库不同,Redux API表面很小.如果删除开发人员警告、注释和健全性判断,则为99 lines.没有需要调试的复杂异步代码.
你实际上可以阅读它并理解Redux的所有内容.
另请参见my answer on downsides of using Redux compared to Flux.