如果 state
是不可变的,那么在任何更改时是否都不需要替换整个状态?否则,你就会改变状态。顶级键是否作为单独的不可变对象(immutable对象)保存?
根据定义,不需要任何更改来替换整个东西吗? Redux 是如何处理这个问题的?替换完整状态不会破坏 PureComponents 吗?
感谢您的澄清。
最佳答案
让我们一步步分解:
- 初始 redux 存储为 { color: 'red' }
- 用户单击按钮
- 已生成一个操作,例如 CHANGE_COLOR
- 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
是一个不同的对象,但 store
和 newStore
都指向 相同 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/