Redux 动作/减速器 vs 直接设置状态

6

我是Redux的新手。 我不太理解actions和reducers与组件直接修改store的价值。

在Redux中,React组件不会直接更改存储。相反,它们会调度一个操作——类似于发布消息。 然后,reducer处理操作——类似于消息订阅者——并响应性地更改状态(更精确地说,创建新状态)。

我觉得这种发布/订阅式的交互添加了层次结构,使人们更难以理解组件实际上在做什么——为什么不允许组件直接将新状态传递给Redux存储?将像this.props.setReduxState这样的东西注入到React组件中是否是一件坏事?

我开始明白为什么状态本身需要不可变(相关问题——Redux不就是强化版全局状态吗?),与检查更新相关,以查看哪些组件道具需要根据状态更改进行更新。 我的问题是额外的操作/ reducer层与直接操作存储相比。


1
可预测性,在我看来非常值得。你看过mobx吗?那似乎是符合你口味的东西 https://github.com/mobxjs/mobx - azium
2
通常情况下,您希望在操作到达reducer并创建新状态之前,通过中间件链传递该操作。您甚至可能希望防止某些操作永远不会触及reducer。这对于权限检查和异步任务等事项特别有用。 - Andrew Winterbotham
2个回答

3
当我决定深入研究Redux时,我有一些非常相似的问题。在我的情况下,我正在使用React内部状态来开发相对较小的应用程序和组件,这仍然非常有效。只有当应用程序和组件数量增加到较大程度时,setState才变得有些笨拙。
我认为这一点并没有强调足够——如果您正在开发相对较小的应用程序或几个组件,并且可以轻松跟踪它们而不需要强大的不可变存储解决方案,则不必总是使用Redux。要开始工作,需要很多必要的样板文件,这在某些情况下可能会过于耗时。
话虽如此,一旦您习惯了React + Redux并拥有自己的样板文件,就可以遵循一个很好的设计范例。Redux本质上偏向于props而不是state,这迫使您采用不可变的设计,因为(通常)无法更改props。这就是Redux DevTools“时间机器”成为可能的原因,以及其他人之前提到的所有中间件。
中间件是其中的重要组成部分,特别是随着更精确的解决方案的出现,例如redux-saga(https://redux-saga.js.org/),用于同步和异步任务。在刚开始时,我认为“thunks”(https://github.com/gaearon/redux-thunk)比sagas更容易理解,除非您已经是生成器的专家,但是在长期内,sagas更加可预测,因此更容易进行测试。
因此,您可以使用一组操作/减速器,而不是每个组件都有一个单独的内部状态,知道您无法错误地改变状态。我发现ImmutableJS(https://facebook.github.io/immutable-js/)和Reselect(https://github.com/reactjs/reselect)的组合非常适合这种情况,这使您可以获得可组合的选择器。无需使用Object.assigns或大量的展开运算符,它会为您创建一个新对象。
我不会急于将现有的非Redux项目转换为Redux,因为工作流程有足够的不同之处,可能会导致重大困惑,但是您很难找到没有Redux的工作流程的新项目的样板文件。例如“React Boilerplate”(https://github.com/react-boilerplate/react-boilerplate),我知道这一点一开始让我感到震惊,但绝对值得了解。它真的测试了您的函数式编程技能。

2
在开发过程中,你经常需要知道是谁和如何改变了状态。通过发出操作来改变状态可以让你保留对这些问题的回答。操作是信息的有效载荷,告诉存储库它应该如何被修改。这些信息以纯JavaScript对象的形式表示,使得这些信息可以被记录、序列化和存储。由于所有的历史记录都被“记住”,所以你可以后续重放所有的操作链以进行调试或测试。结合像Redux DevTools这样的工具,可以使开发过程变得非常容易和惊人。由于所有的存储修改都被记录到监视器中,所以你可以看到每一步状态是如何被修改的,甚至可以回溯或前进到操作链中的任意位置。
将所有的变化集中在一个地方的另一个好处是更容易控制状态。这保证了所有的变化按照严格的顺序一个接一个地发生,而没有回调会使应用程序的行为不稳定。这也允许在一个地方保留某些操作共同的功能,或者换句话说,应用中间件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接