Redux 作者在这里!
Redux与 Flux没有什么不同。总体而言,它具有相同的架构,但 Redux 能够通过使用 Flux 使用回调注册的功能组合来减少一些复杂性。
Redux 没有根本区别,但我发现它使某些抽象更容易,或者至少可以实现,而这在 Flux 中很难或不可能实现。
减速机组成
以分页为例。我的Flux + React Router 示例处理分页,但代码很糟糕。糟糕的原因之一是Flux 使得跨商店重用功能变得不自然。如果两个存储需要处理分页以响应不同的操作,它们要么需要从公共基本存储继承(糟糕!当您使用继承时,您将自己锁定在特定设计中),或者从内部调用外部定义的函数事件处理程序,它需要以某种方式对 Flux 存储的私有状态进行操作。整件事很混乱(尽管绝对是在可能的范围内)。
另一方面,由于 reducer 组合,Redux 分页是自然的。它一直是减速器,因此您可以编写一个减速器工厂来生成分页减速器,然后在减速器树中使用它。之所以如此简单,关键是因为在 Flux 中,存储是扁平的,但在 Redux 中,reducer 可以通过函数组合进行嵌套,就像 React 组件可以嵌套一样。
这种模式还支持无用户代码undo/redo等精彩功能。您能想象将 Undo/Redo 插入 Flux 应用程序是两行代码吗?几乎不。使用 Redux,再次感谢 reducer 组合模式。我需要强调的是,它并没有什么新鲜之处——这是Elm Architecture 中开创和详细描述的模式,它本身受 Flux 的影响。
服务器渲染
人们一直在使用 Flux 在服务器上进行渲染,但是看到我们有 20 个 Flux 库,每个库都试图使服务器渲染“更容易”,也许 Flux 在服务器上有一些粗糙的边缘。事实上,Facebook 并没有做太多的服务器渲染,所以他们并没有很关心它,并依靠生态系统来让它变得更容易。
在传统的 Flux 中,商店是单身人士。这意味着很难将服务器上不同请求的数据分开。不是不可能,但很难。这就是为什么大多数 Flux 库(以及新的Flux Utils)现在建议您使用类而不是单例,以便您可以根据请求实例化存储。
您仍然需要在 Flux 中解决以下问题(您自己或借助您最喜欢的 Flux 库,例如Flummox或Alt):
- 如果商店是类,我如何根据请求使用调度程序创建和销毁它们?我什么时候注册商店?
- 我如何从存储中提取数据,然后在客户端上重新提取数据?我需要为此实施特殊方法吗?
诚然,Flux 框架(不是 vanilla Flux)可以解决这些问题,但我发现它们过于复杂。例如,Flummox 要求您在您的商店中实施serialize()
和deserialize()
。Alt 通过提供takeSnapshot()
在 JSON 树中自动序列化您的状态来更好地解决这个问题。
Redux 更进一步:由于只有一个 store(由许多 reducer 管理),因此您不需要任何特殊的 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、路由、不变性开发检查、持久性等用例。并非所有这些都会有用,但是能够访问一组可以轻松组合在一起工作的工具是很好的。
简单
Redux 保留了 Flux 的所有优点(记录和重放动作、单向数据流、依赖突变)并增加了新的优点(容易撤销重做、热重载),而没有引入 Dispatcher 和存储注册。
保持简单很重要,因为它可以让您在实现更高级别的抽象时保持理智。
与大多数 Flux 库不同,Redux API 表面很小。如果您删除开发人员警告、评论和健全性检查,则为99 行。没有需要调试的棘手异步代码。
您实际上可以阅读它并了解所有 Redux。
另请参阅我对使用 Redux 与 Flux 相比的缺点的回答。