我已经阅读了this answer,reducing boilerplate个,看了几个GitHub示例,甚至try 了一点Redux(TODO应用程序).

据我所知,与传统的MVC架构相比,official redux doc motivations提供了优势.但它并没有回答这个问题:

Why you should use Redux over Facebook Flux?

Is that only a question of programming styles: functional vs non-functional? Or the question is in abilities/dev-tools that follow from redux approach? Maybe scaling? Or testing?

Am I right if I say that redux is a flux for people who come from functional languages?

To answer this question you may compare the complexity of implementation redux's motivation points on flux vs redux.

以下是official redux doc motivations分的激励点:

  1. 处理乐观更新(as I understand, it hardly depends on 5th point. Is it hard to implement it in facebook flux?)
  2. 在服务器上渲染(facebook flux also can do this. Any benefits comparing to redux?)
  3. 在执行路由转换之前获取数据(Why it can't be achieved in facebook flux? What's the benefits?)
  4. 热重新加载(It's possible with 100. Why do we need redux?)
  5. undo撤消/重做功能
  6. 还有其他要点吗?就像持续的状态...

推荐答案

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库,如FlummoxAlt):

  • 如果存储是类,我如何使用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.它的设计考虑了loggingPromisesObservablesroutingimmutability dev checkspersistence等用例.并不是所有这些都会有用,但有机会使用一套可以轻松组合在一起工作的工具是很好的.

简单

Redux保留了Flux的所有好处(动作的记录和重放、单向数据流、依赖性Mutations ),并在不引入Dispatcher和store注册的情况下增加了新的好处(轻松撤销重做、热重新加载).

保持它的简单是很重要的,因为当你实现更高层次的抽象时,它可以让你保持理智.

与大多数通量库不同,Redux API表面很小.如果删除开发人员警告、注释和健全性判断,则为99 lines.没有需要调试的复杂异步代码.

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


另请参见my answer on downsides of using Redux compared to Flux.

Javascript相关问答推荐

ReactJS中的material UI自动完成类别

是否有方法在OpenWeatherMap API中获取过go 的降水数据?

如何分配类型脚本中具有不同/额外参数的函数类型

我在这个黑暗模式按钮上做错了什么?

从PWA中的内部存储读取文件

yarn安装一个本地npm包,以便本地包使用main项目的node_modules(ckeditor-duplicated-modules错误)

自定义高图中的x轴标签序列

如何在模块层面提供服务?

如何从隐藏/显示中删除其中一个点击?

如何在JavaScript文件中使用Json文件

如何在bslib nav_insert之后更改导航标签的CSS类和样式?

在WordPress中使用带有WPCode的Java代码片段时出现意外令牌错误

TypeError:无法读取未定义的属性(正在读取';宽度';)

为什么可选参数的顺序会导致问题?

删除元素属性或样式属性的首选方法

匹配一个或多个可选重复的特定模式

JAVASCRIPT SWITCH CASE语句:当表达式为';ALL';

为什么在运行于<;img>;事件处理程序中的JavaScript中x和y是不可变的?

如何将对象推送到firestore数组?

带元素数组的Mongo聚合