【问题标题】:How is state immutability actually used in Redux?Redux 中如何实际使用状态不变性?
【发布时间】:2016-06-28 11:40:34
【问题描述】:

我试图了解在 Redux 中实际(如果有的话)如何使用不变性。我发现的每个教程/文章/文档都指出,reducers 永远不应该更改状态对象,而是创建更改数据的新副本(即 reducer 必须是纯函数)。我理解这一点,但我找不到任何地方解释 Redux 内部实现如何实际使用该指南。

这只是一个强烈的建议,还是如果我将 reducer 设为非纯,Redux 内部的某些东西会中断?

如果是后者,那么究竟会破坏什么?

我确实找到了几个地方,丹说在某些(非常罕见的)情况下,reducer 可能不是纯的,但它是有风险的(同样,没有解释究竟是什么风险)。

【问题讨论】:

    标签: immutability redux


    【解决方案1】:

    Redux 与 React 一起使用时,通常使用来自 react-reduxconnect 连接。用connect 包装一个组件,通过指定一个更改处理程序来订阅对redux 存储的更改,该处理程序在分派操作并调用reducers 后被调用。在调用更改处理程序时,connect 使用身份比较 (previousState !== newState) 将存储的当前状态与新状态进行比较——这比进行浅层或深层比较要快——并且仅当两个状态不是时相同,它是否使用setState 更新包装的组件。直接改变状态不会导致引用发生变化,从而导致被包装的组件不会重新渲染。

    这是connect 确定它是否应该调用 setState 的方式:

    if (!pure || prevStoreState !== storeState) {
      this.hasStoreStateChanged = true
      this.setState({ storeState })
    }
    

    connect 还提供了一个选项来覆盖此行为,方法是指定包装的组件不是纯使用:

    connect(mapStateToProps, mapDispatchToProps, mergeProps, {pure: false} )

    纯组件也可以通过实现shouldComponentUpdate来使用身份比较,以防止对render的不必要调用。

    TL;DR:如果商店的状态由于突变而发生变化,则用 connect 包裹的组件将不会重新渲染。

    编辑:Redux 本身不会损坏任何东西,因为它太小了以至于它不会尝试检查 reducer 返回的状态。

    【讨论】:

    • TL;DR:不可变的数据结构可以很容易地检测到是否发生了变化,这对渲染性能有很大的提升。
    • 感谢您的回答,但我的问题是关于 Redux 本身而不是使用它的组件(我将编辑问题以使其更清楚)。如果 reducer 不纯,你知道 Redux 中的某些东西是否会中断吗?
    • 另一个要考虑的因素是时间旅行调试。如果 reducer 是纯的,那么调用它的 what 状态和操作都无关紧要,它始终具有相同的输出。这意味着 Redux DevTools 可以通过不同的操作来回运行,最终结果将是“正确的”。如果reducer 改变状态,时间旅行能力就会中断。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    • 1970-01-01
    • 2017-07-17
    • 2019-08-06
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多