可以将redux视为pub / sub或observer模式吗?

时间:2016-10-11 12:43:59

标签: javascript reactjs redux

我只是试图了解react.js,有人说,我刚刚在网上完成了一些教程。

我是redux的新手,这是我观看的一些视频教程的一部分。我越是深入研究它,就redux取代了react.js的最初想法而言,对我来说意义越小。在反应过程中,组件具有自己的状态,可以通过道具向下传递,以保持工作流程从上到下。

使用redux,我们现在尝试使整个应用程序状态为全局,并且我们必须定义操作来操纵该(全局)状态,那么除了" normal"之外的其他操作是什么? javascript pub / sub或observer模式?或者也许我弄错了? - 非常感谢澄清。

2 个答案:

答案 0 :(得分:41)

Redux不应该"取代react.js"的最初想法,认为它更像是一个库来管理组件之间的共享状态和协调状态突变。 Redux确实使用了pub / sub模式,请参阅这里的store方法: http://redux.js.org/docs/api/Store.html#store-methods 您将找到组件用于订阅状态树中的更改的subscribe方法。通常你不直接使用store.subscribe,因为Redux-React绑定(基本上是Redux connect)为你做的。你可以在这里查看实际的实现,并不是很复杂(实际上对我来说,Redux的主要好处是其他Flux实现):https://github.com/reactjs/react-redux/blob/master/src/components/connect.js#L199

除了订阅商店发出的更改之外,该代码还执行一些优化,例如将新道具传递给组件(从而触发重新渲染),只有在真正需要时才会这样做。 / p>

还要考虑将组件内部状态与Redux一起使用完全没问题。您可以使用内部状态来存储您不需要/想要与其他组件共享的状态。

当你有一个更复杂的应用程序时,你会发现需要类似Redux的东西,顶层组件需要相互通信(动作)并以某种方式共享某些状态。

Redux中的操作默认情况下只是POJO(普通的旧javascript对象),您可以将它们视为"事件"您经常发送以响应用户触发的操作(例如,用户点击按钮),但您不仅限于此,您可以从任何地方发送操作。 Redux存储侦听这些操作并调用reducers(纯函数)传递您调度的操作对象。

Reducers拦截所有已调度的操作,并且可以为他们管理的状态片返回一个新的更新状态。

从这个意义上说,reducer是一个处理动作并根据需要更新状态的函数。

反过来,当reducer通过返回状态的新副本来更新状态时,连接的组件(订阅状态中的更改)将被传递新的props并将重新呈现以反映更改。

有时,调度普通的js对象是不够的,你需要更多的控制。当您需要执行更复杂的逻辑时,这变得很清楚,例如,当您需要根据AJAX调用的响应更新状态中的计数器时。

使用redux-thunk,您可以调度函数而不仅仅是普通对象。通过调度函数,您可以非常简单的方式有效地实现控制模式的反转。你的行动变成了一个"食谱"由函数描述,而不仅仅是一个简单的语句,就像POJO动作一样。

为什么只支持POJO"开箱即用",对于行动,为什么没有基本的Action类或什么?主要是因为没有必要。一个简单的对象(基本上被视为值的包)具有type属性是您真正需要的,它基本上是最简单的可能接口。您可以将此视为针对接口(操作)而不是实现进行编程。

为什么全局状态更好,而不是每个组件管理自己的状态?主要是因为管理状态实际上是非平凡的js应用程序中最难的部分。通过使用Redux,您可以从UI层中提取所有逻辑,从而使测试更容易。事实上,理想情况下,您应该能够测试所有真实的业务逻辑。一个Redux应用程序,甚至没有渲染单个组件。

组件成为" dumber" "更纯粹"因为他们只是呈现他们被告知要做的事情。 "较纯"这意味着因为它们不会保持任何状态,所以你看到的渲染只取决于任何给定时间点的输入(读取"道具"),而不是任何历史,因此&# 34;无国籍"

将状态作为单个,json可序列化对象也可以轻松调试,对其进行快照以及从服务器或本地存储发送/恢复。

答案 1 :(得分:9)

不能upvote Fabios回答两次,评论部分是小的:

是的,在我看来,它就像一个带有约定的pub / sub。

为了说明传递道具是多么痛苦,这是一个例子。

假设您有一个显示当前登录用户的组件。您的组件层次结构就像一棵巨大的树。现在,如果您要在从根开始的分支上显示该组件,并且在从根开始的另一个分支中显示该组件,则在层次结构中的每个深层深处,您必须将用户信息从根组件传递到叶节点上2条不同的路径,污染了每个组件的道具(与用户的信息完全无关,但现在他们需要知道)。