我已阅读this answer,reducing boilerplate,查看了几个GitHub示例,甚至尝试了redux(todo apps)。
据我了解,official redux doc motivations提供了与传统MVC架构相比的优点。但它没有提供问题的答案:
为什么你应该使用Redux而不是Facebook Flux?
这只是编程风格的问题:功能与非功能?或者问题是在redux方法中遵循的能力/开发工具?也许缩放?还是测试?
如果我说redux对于来自函数式语言的人来说是一种变化,我是对的吗?
要回答这个问题,您可以比较实施redux在通量与减少量上的动机点的复杂性。
以下是official redux doc motivations的动机要点:
答案 0 :(得分:1959)
Redux作者在这里!
Redux不是 与Flux不同。总体而言,它具有相同的架构,但Redux能够通过使用Flux使用回调注册的功能组合来削减一些复杂角落。
Redux没有根本的区别,但我发现它使得某些抽象更容易,或者至少可以实现,这在Flux中很难或不可能实现。
以分页为例。我的Flux + React Router example处理分页,但代码很糟糕。其中一个可怕的原因是 Flux使得跨商店重用功能变得不自然。如果两个商店需要处理分页以响应不同的操作,他们要么需要继承共同的基本存储(糟糕!当您使用继承时,您将自己锁定到特定设计中),或者从事件处理程序中调用外部定义的函数,这将需要以某种方式操作Flux存储的私有状态。整件事情很混乱(虽然绝对是可能的)。
另一方面,由于减速剂成分,Redux分页很自然。它的减速器一直向下,所以你可以写reducer factory that generates pagination reducers然后use it in your reducer tree。它之所以如此简单的关键是因为在Flux中,商店是平的,但在Redux中,reducer可以通过功能组合嵌套,就像React组件可以嵌套一样。
此模式还支持非用户代码undo/redo等精彩功能。 您能想象将Undo / Redo插入到两行代码的Flux应用程序中吗?几乎不。由于减速器组成模式,使用Redux,它是 - 重要的。我需要强调其中没有什么新鲜事 - 这是Elm Architecture中开创并详细描述的模式,它本身受到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通过提供{J}树中自动序列化状态的takeSnapshot()
来解决这个问题。
Redux更进一步:因为只有一个商店(由许多减速机管理),你不需要任何特殊的API来管理(重新)水合作用。你不要&# 39;需要“冲洗”或“保湿”商店 - 只有一个商店,您可以读取其当前状态,或创建一个新状态的商店。每个请求都有一个单独的商店实例。 Read more about server rendering with Redux.
同样,这是一个可能在Flux和Redux中都有可能的情况,但是Flux库通过引入大量的API和约定来解决这个问题,而且Redux甚至不必解决它,因为它没有&#39由于概念上的简单性,首先出现了这个问题。
我实际上并不打算让Redux成为一个受欢迎的Flux库 - 我在写ReactEurope talk on hot reloading with time travel时正在编写它。我有一个主要目标:可以动态更改减速器代码,甚至可以通过交叉操作“改变过去”,并查看重新计算的状态。
我还没有看到一个能够做到这一点的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的所有内容。
答案 1 :(得分:101)
首先,完全可以使用React编写应用程序 通量。
我创建的这个视觉图是为了快速查看两者,对于那些不想阅读整个解释的人来说,这可能是一个快速的答案:
但如果您仍然对此了解更多,请继续阅读。
我相信你应该从纯粹的React开始,然后学习Redux和Flux。 在你有了React的真实经验之后,你会看到 Redux是否对你有帮助。
也许你会觉得Redux完全适合你的应用,也许你 会发现,Redux正试图解决你不是的问题 真的很有经验。
如果您直接使用Redux,最终可能会过度设计 代码,代码更难维护,甚至更多的错误 终极版。
来自Redux docs:
动机
由于JavaScript单页面应用程序的要求变得越来越复杂,我们的 代码必须管理比以往更多的状态。这个州可以包括 服务器响应和缓存数据,以及本地创建的数据 尚未坚持到服务器。 UI状态也在增加 复杂性,因为我们需要管理活动路线,选定的标签, 旋转器,分页控件等。管理这个不断变化的状态很难。如果模型可以更新 另一个模型,然后视图可以更新模型,更新另一个模型 模型,反过来,这可能会导致另一个视图更新。在某些 请注意,您不再了解您的应用中发生的事情 失去对其状态的时间,原因和方式的控制。当一个系统 是不透明和不确定的,很难重现错误或添加 新功能。
好像这还不够糟糕,请考虑新的要求 在前端产品开发中很常见。作为开发人员,我们是 期望处理乐观更新,服务器端呈现,提取 执行路由转换之前的数据,等等。我们发现自己 试图管理我们从未必须处理的复杂性 之前,我们不可避免地提出这样一个问题:是时候放弃了吗?该 答案是否。
这种复杂性很难处理,因为我们混合了两个概念 这是人类思维难以推理的原因:突变和 异步性。我称他们为Mentos和Coke。两者都很棒 分开,但他们在一起造成一团糟。像React这样的图书馆 尝试通过删除两者来解决视图层中的此问题 异步和直接DOM操作。但是,管理状态 您的数据由您自己决定。这就是Redux的用武之地。
追随Flux,CQRS和Event Sourcing,Redux的脚步 试图通过强加某些来预测状态突变 更新如何以及何时发生的限制。这些限制 反映在Redux的三个原则中。
同样来自Redux docs:
核心概念
Redux本身非常简单。想象一下,您的应用的状态被描述为普通对象。例如, 待办事项应用程序的状态可能如下所示:
{ todos: [{ text: 'Eat food', completed: true }, { text: 'Exercise', completed: false }], visibilityFilter: 'SHOW_COMPLETED' }
这个对象就像一个“模型”,除了没有setter。这个 是这样,代码的不同部分不能改变状态 任意地,导致难以重现的错误。
要更改状态中的某些内容,您需要发送操作。一个 action是一个普通的JavaScript对象(请注意我们如何不引入任何内容 魔术?)描述发生了什么。以下是一些示例操作:
{ type: 'ADD_TODO', text: 'Go to swimming pool' } { type: 'TOGGLE_TODO', index: 1 } { type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
强制将每个更改描述为一个动作让我们拥有一个 清楚地了解应用程序中发生了什么。如果有的话 改变了,我们知道它为什么会改变。行动就像是面包屑 已经发生了。最后,为了将状态和行动联系起来,我们写了一个 函数称为reducer。再一次,没有什么神奇之处 - 它只是一个 将state和action作为参数的函数,并返回 该应用的下一个状态。要为a编写这样的函数会很困难 大应用程序,所以我们编写管理州的部分的较小功能:
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; } }
我们编写了另一个管理我们完整状态的reducer 应用程序通过调用相应的状态键的两个Reducer:
function todoApp(state = {}, action) { return { todos: todos(state.todos, action), visibilityFilter: visibilityFilter(state.visibilityFilter, action) }; }
这基本上是Redux的整个想法。请注意,我们还没有使用过 任何Redux API。它附带了一些实用程序来促进这一点 模式,但主要的想法是你描述你的状态 随着时间的推移更新以响应操作对象和90%的代码 你写的只是简单的JavaScript,没有使用Redux本身 API,或任何魔术。
答案 2 :(得分:57)
你可能最好开始阅读Dan Abramov的这篇文章,他在撰写redux时讨论了Flux的各种实现及其权衡: The Evolution of Flux Frameworks
其次,您链接的动机页面并没有真正讨论Redux的动机,而是Flux(和React)背后的动机。 Three Principles更具特定于Redux,但仍然没有处理与标准Flux架构的实现差异。
基本上,Flux有多个商店,可以响应UI / API与组件的交互来计算状态变化,并将这些更改作为组件可以订阅的事件进行广播。在Redux中,每个组件只有一个商店订阅。 IMO感觉至少像Redux通过统一(或减少,如Redux所说)数据流回到组件来进一步简化和统一数据流 - 而Flux专注于统一数据流的另一面 - 查看到模型。
答案 3 :(得分:27)
我是早期采用者,并使用Facebook Flux库实施了一个中型单页应用程序。
由于我在谈话中迟到了,我只是指出,尽管我最好的希望Facebook似乎认为他们的Flux实施是一个概念证明,它从未得到应有的关注。
我鼓励你玩它,因为它暴露了Flux架构的更多内部工作,这是非常有教育意义的,但同时它没有提供像Redux这样的库提供的许多好处(这对小型项目来说并不重要,但对大型项目来说非常有价值)。
我们决定继续前进,我们将转向Redux,我建议你也这样做;)
答案 4 :(得分:20)
以下是Redux over Flux的简单解释。
Redux没有调度程序。它依赖于名为reducers的纯函数。它不需要调度员。每个操作由一个或多个Reducer处理以更新单个存储。由于数据是不可变的,因此reducers返回更新商店
了解更多信息Flux vs Redux
答案 5 :(得分:6)
我使用Flux工作了很长时间,现在使用Redux已经很长时间了。正如丹指出的那样,两种架构都没有那么不同。事情是,Redux使事情更简单,更清洁。它会在Flux上教你一些东西。例如,Flux是单向数据流的完美示例。我们将数据,操作和视图层分开的关注点分离。在Redux中我们有相同的东西,但我们也学习了不变性和纯函数。
答案 6 :(得分:5)
从一个新的react / redux采用者从ExtJS(几年)于2018年中期开始迁移:
向后滑下redux学习曲线后,我遇到了相同的问题,并认为纯通量像OP一样简单。
我很快看到了redux相对于通量的好处,如上面的答案所述,并且正在将其用于我的第一个应用程序中。
在再次抓住样板时,我尝试了一些 other 状态管理库,发现的最好的是rematch。
它比香草Redux直观得多,它减少了90%的样板,减少了我花在Redux上的时间的75%(我认为图书馆应该这样做) ,我马上就可以使用几个企业应用程序。
它也可以使用相同的redux工具运行。这是good article,涵盖了一些好处。
因此,对于到达此SO职位搜索“更简单的redux”的任何人,我建议尝试使用它作为redux的一种简单替代方法,它具有所有优势和1/4的样板。
答案 7 :(得分:0)
最好使用MobX来管理应用程序中的数据以获得更好的性能,而不是Redux。