React-Redux:应该将所有组件状态保存在Redux Store中


89

说我有一个简单的切换:

当我单击按钮时,颜色组件在红色和蓝色之间切换

我可以通过执行以下操作来达到此结果。

index.js

Button: onClick={()=>{dispatch(changeColor())}}
Color: this.props.color ? blue : red

container.js

connect(mapStateToProps)(indexPage)

action_creator.js

function changeColor(){
 return {type: 'CHANGE_COLOR'}
}

reducer.js

switch(){
case 'CHANGE_COLOR':
return {color: true}

但这是很多代码的地狱,我可以用jQuery,一些类和一些CSS在5秒钟内完成一些事情。

所以我想我真正要问的是,我在这里做错了什么?


6
react-redux不以比jquery短的形式出售。它肯定需要一些代码来启动和运行。
zerkms's

1
在这里看看:github.com/rackt/redux/issues/1287关于这个主题有很多很好的讨论。
m0meni 2016年

1
谢谢@ AR7那就是完美
l2silver

1
@ l2silver没问题。基本上,想法是,如果该组件的颜色对其他任何人都无关紧要,则只需将该状态保留在组件本身内部即可。
m0meni

2
AR7提到的问题已经转移:github.com/reactjs/redux/issues/1287
ptim

Answers:


154

Redux主要用于“应用程序状态”。也就是说,任何与您的应用程序逻辑有关的内容。建立在其顶部的视图是该状态的反映,但不必为执行的所有操作仅使用该状态容器。

只需问以下问题:该状态对应用程序的其余部分是否重要?应用程序的其他部分是否会基于该状态而有所不同?在许多较小的情况下,情况并非如此。下拉菜单:打开或关闭的事实可能不会对应用程序的其他部分产生影响。因此,将其连接到您的商店可能是过大的选择。这当然是一个有效的选择,但并没有真正给您带来任何好处。最好this.state每天使用并调用它。

在您的特定示例中,切换按钮的颜色是否会对应用程序的其他部分产生影响?如果它是应用程序主要部分的某种全局开/关切换,则它肯定属于商店。但是,如果您只是在单击按钮时切换按钮颜色,则可以将颜色状态保留为本地定义。单击按钮的动作可能还具有其他需要动作分派的效果,但这与应该使用什么颜色的简单问题是分开的。

通常,请尝试使应用程序状态尽可能小。您不必将所有东西都推到那里。在需要时执行此操作,或者将某些内容保留在其中很有意义。或者,如果使用开发工具可以使您的生活更轻松。但是不要过多地强调它的重要性。


嘿,我知道永远不会有这个问题的明确答案,但是我认为您的逻辑在这里很合理
l2silver

3
老实说,我根本没有真正知道使用该flux / redux东西的意义。事件驱动模型有什么问题?
jayarjo '16

海事组织,这不是完美的答案。这取决于。将ui状态存储为反应状态将使redux存储干净,但最终将导致难以测试的非功能组件。将ui状态存储为react状态时,将需要在dev上进行大量工作,因为我们必须编写额外的reducer。但是,有很多软件包可以帮助您将ui状态更轻松地存储在redux中,请查看redux.js.org/docs/faq/OrganizingState.html了解更多详细信息。
罗恩

19

Redux常见问题解答:组织说明Redux
官方文档的这一部分很好地回答了您的问题。

使用本地组件状态很好。作为开发人员,确定应用程序构成哪种状态以及每种状态应驻留的位置是您的工作。找到一个适合您的天平,然后继续前进。

用于确定应将哪种数据放入Redux的一些通用经验法则:

  • 应用程序的其他部分是否关心此数据?
  • 您是否需要能够基于此原始数据创建其他派生数据?
  • 是否使用相同的数据来驱动多个组件?
  • 能够将这种状态恢复到给定的时间点(例如,时间旅行调试)对您有价值吗?
  • 您是否要缓存数据(即,使用已存在的状态而不是重新请求)?

6

为了突出显示@ AR7提供的出色链接,并且因为该链接向后移动了一段时间,所以:

将React用于短暂状态,该状态对应用程序全局无关紧要,并且不会以复杂的方式进行更改。例如,在某些UI元素中切换,即表单输入状态。将Redux用于全局重要的状态或以复杂方式突变的状态。例如,缓存的用户或后期草稿。

有时,您可能希望从Redux状态转换为React状态(当在Redux中存储内容变得笨拙时),或者反过来(当更多组件需要访问某些曾经是本地的状态时)。

经验法则是:做些不太尴尬的事情。

丹·阿布拉莫夫(Dan Abramov):https : //github.com/reactjs/redux/issues/1287#issuecomment-175351978


-7

是的,值得努力将所有组件状态存储在Redux中。如果这样做,您将受益于Redux的许多功能,例如时间旅行调试和可重播的错误报告。如果您不这样做,那么这些功能可能会完全不可用

每当您不在 Redux中存储组件状态更改时,该更改就会从Redux更改堆栈中完全丢失,并且您的应用程序UI将与存储不同步。如果这对您不重要,请问自己为什么要完全使用Redux?没有它,您的应用程序将不再那么复杂!

出于性能方面的考虑,您可能希望退回可this.setState()重复执行许多操作的任何操作。例如:每次用户键入键时,将输入字段的状态存储在Redux中可能会导致性能下降。您可以通过将其视为事务来解决此问题:用户操作“提交”后,将最终状态保存在Redux中。

您的原始帖子提到Redux方式是如何“编写大量代码的”。是的,但是您可以将抽象用于常见的模式,例如本地组件状态。


改进的调试是redux的有用目标和一个不错的功能,但是我认为信噪比也很重要。可以将每个变量记录在代码库中,但是这会添加很多额外的代码,从而使实际代码更难以阅读,并且记录也很难遍历。我认为使用redux也是一样。将所有状态都放在redux中可以改善调试,但是会增加其他代码和抽象的成本,这会使代码更难以阅读,甚至使某些调试任务变得更难。(当redux开发工具崩溃时,很多调试收益都将丢失。)
JD Sandifer

1
那为什么要完全使用Redux?如果您没有将所有内容都放在Redux中,则会失去所有功能,例如devtools。真的是全有还是全无。如果将setState()用于下拉菜单(如本文顶部答案),则无法使用devtools调试用户在下拉菜单中可能遇到的任何问题。当您将setState()用于叠加层时,情况更糟,因为在叠加层显示之前和之后都没有时间旅行。在这里撒上setState(),很容易出错,因为开发人员必须不断考虑可能发生的问题。
kumar303

作为更具体的答复,在代码库中记录每个变量并不是一个有用的隐喻,因为问题在于是否使用this.setState()dispatch(action...)。一个人不需要在this.setState()所有地方都使用它,但我的建议是在99%的情况下使用Redux代替,this.setState()基于性能方面的考虑,回落到1%。
kumar303

在我看来,记录每个变量类似于将所有内容都放入Redux中,并且通常不建议这样做。留下一些东西出来终极版并不否定了这一切的特征在终极版,只要状态被分离。即,即使选择框的状态不是,我仍然可以调试通过Redux传递的API调用逻辑。OP有一点-需要在多个位置使用更多代码才能使用Redux,也许在列出的特定示例中没有道理。
JD Sandifer

实际上,您可能无法调试API逻辑。这就是我的意思。很难预见您会中断时间旅行的情况,因此最好将所有状态(包括选择框状态)放入Redux,直到出现性能问题。
kumar303
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.