javascript - 如果状态是不可变的,那么整个状态是否会在任何更改时被替换?

标签 javascript reactjs redux

如果 state 是不可变的,那么在任何更改时是否都不需要替换整个状态?否则,你就会改变状态。顶级键是否作为单独的不可变对象(immutable对象)保存?

根据定义,不需要任何更改来替换整个东西吗? Redux 是如何处理这个问题的?替换完整状态不会破坏 PureComponents 吗?

感谢您的澄清。

最佳答案

让我们一步步分解:

  1. 初始 redux 存储为 { color: 'red' }
  2. 用户单击按钮
  3. 已生成一个操作,例如 CHANGE_COLOR
  4. Redux 使用存储(从步骤 1 开始)和操​​作来调用您的 reducer 。 reducer 返回一个新存储,例如 { color: 'blue' }

然后,假设您有一个 class Square extends PureComponent ,其中 mapStateToProps(store) => { color: store.color }

现在发生的情况是,当存储发生更改时,redux-react 每次都会运行mapStateToProps。然后它会生成新的 Prop 。这些 Prop 被发送以使用react。

如果您到目前为止对 redux 和 React 如何协同工作的 TL;DR 是这样的,每当 redux 存储发生更改时,每个 mapStateToProps 都会运行,这会为您的 React 组件生成新的 props。

从现在开始,它就是标准的 React。当 React 组件的 props 发生变化时,它会运行 componentWillReceiveProps ,然后运行 ​​shouldComponentUpdate

对于 PureComponent 来说,基本上这意味着 shouldComponentUpdate 只是对新的 props 进行浅层相等检查,然后从那里开始。

<小时/>

好吧,有了这个基本的理解,嵌套对象的行为就类似了。

如果我们有一个像这样的商店,而不是 {color: 'red'} 的商店,会怎样:

{
  allMyData: {
    color: 'red'
    key1: 'someData',
    key2: 'lotsMoreData',
    bigData: {
     nestedKey: 'EvenMoreNestedData',
    }

}

然后,你的 reducer 可能看起来像这样:

const reducer = (store, action) => {
  if (action == CHANGE_COLOR) {
    let newStore = Object.assign({}, store);
    newStore.allMyData = Object.assign({}, newStore.allMyData, { color: 'blue' });

  }
}

请注意,有更好的工具可以进行深度不可变合并。我想在这里展示的一个要点是,虽然 newStore 是一个不同的对象,但 storenewStore 都指向 相同 bigData 键和其他未更改的值。不变性部分允许这种事情发挥作用。

之后的步骤基本是一样的。每次存储更改后,mapStateToProps 都会运行并生成一个新的 props 对象。然后,Redux-react 将该新的 prop 对象传递给 React,在这种情况下,如果 prop 值具有相同的标识,则 PureComponent 将不会渲染 (===)

请注意,redux-react 有一些性能优化,它将避免使用新的 props 调用 React,但出于本次讨论的目的,我省略了该步骤。

希望这有助于解答您的疑问。

TL;DR:每个 redux 操作都会返回一个新存储。每次生成新的 store 时,mapStateToProps 都会为每个连接的 React 组件生成新的 props。如果react组件是pureComponent,它不会重新渲染,因为props没有改变。

您问题的关键在于,由于您的存储是不可变的,因此您可以在不同的存储中重复使用相同的内部对象,甚至可以通过 mapStateToProps 将这些传递到您的 React 组件中。

关于javascript - 如果状态是不可变的,那么整个状态是否会在任何更改时被替换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44956065/

相关文章:

java - 是否可以使用 JSP/JSTL 生成动态 css/javascript 文件?

javascript - Chrome Javascript 日期上午 |下午

javascript - 我如何处理 setState 中的 promise ?

javascript - 在 React 钩子(Hook)中的另一个卸载 useEffect 中,状态的改变不会受到影响

javascript - Redux - 正确调度操作

javascript - 在 mouseenter 和 mouseleave 上暂停并重新启动 CSS 过渡

javascript - 谁可以向 grunt-wiredep 生成的 URL 附加前缀和后缀?

reactjs - 如何使样式库可配置

javascript - 如何使用 React 从对象列表创建表格?

javascript - 从 React TypeScript 组件调用外部 Javascript 函数