扩展运算符与 JSON.parse(JSON.stringify(...)) 对于不可变对象
Spread operator vs JSON.parse(JSON.stringify(...)) for immutable objects
我正在使用 Redux,最近 运行 遇到了一个问题,我正在向数组添加消息,而 Redux 状态没有在 React 上发出重新渲染。为此,我正在使用 react-redux
库。这是我遇到的问题的示例:
// State structure
structure: { messages: {}, groups: {} }
// ---
newState = { ...prevState };
newState.messages[action.message.group] = action.message;
return newState;
这是在更新状态,但是它没有触发对反应组件的更新,但是用 newState = JSON.parse(JSON.stringify(prevState))
替换 newState = { ...prevState }
解决了这个问题。
谁能详细解释一下为什么会这样?我的印象是传播运算符创建了对象的克隆,直到现在我才遇到任何问题。
react-redux 连接组件进行浅层严格相等性检查以决定它们是否要更新。见 http://redux.js.org/docs/faq/ImmutableData.html
展开运算符类似于Object.assign,不会深度克隆对象。 JSON 起作用的原因是因为您创建了一个全新的对象,它可以通过严格的相等性检查,但是您的所有组件都会不必要地更新,因为现在没有任何东西可以通过严格的相等性检查。
Object.assign({}, ...prevState, ...newState) 会创建一个新的顶级对象,但不会为嵌套在 prevState 或 newState 中的任何对象创建新对象。但是,您必须小心更新嵌套对象以避免不必要的重新渲染。对于深度嵌套的对象和数组,这可能会变得棘手。
我建议检查用于管理状态的无缝不可变或不可变包。此外,reselect 库可以帮助您提取特定于组件需求的记忆对象。
2020 年 8 月 16 日更新
immer 库是当今最好的状态管理库之一
我正在使用 Redux,最近 运行 遇到了一个问题,我正在向数组添加消息,而 Redux 状态没有在 React 上发出重新渲染。为此,我正在使用 react-redux
库。这是我遇到的问题的示例:
// State structure
structure: { messages: {}, groups: {} }
// ---
newState = { ...prevState };
newState.messages[action.message.group] = action.message;
return newState;
这是在更新状态,但是它没有触发对反应组件的更新,但是用 newState = JSON.parse(JSON.stringify(prevState))
替换 newState = { ...prevState }
解决了这个问题。
谁能详细解释一下为什么会这样?我的印象是传播运算符创建了对象的克隆,直到现在我才遇到任何问题。
react-redux 连接组件进行浅层严格相等性检查以决定它们是否要更新。见 http://redux.js.org/docs/faq/ImmutableData.html
展开运算符类似于Object.assign,不会深度克隆对象。 JSON 起作用的原因是因为您创建了一个全新的对象,它可以通过严格的相等性检查,但是您的所有组件都会不必要地更新,因为现在没有任何东西可以通过严格的相等性检查。
Object.assign({}, ...prevState, ...newState) 会创建一个新的顶级对象,但不会为嵌套在 prevState 或 newState 中的任何对象创建新对象。但是,您必须小心更新嵌套对象以避免不必要的重新渲染。对于深度嵌套的对象和数组,这可能会变得棘手。
我建议检查用于管理状态的无缝不可变或不可变包。此外,reselect 库可以帮助您提取特定于组件需求的记忆对象。
2020 年 8 月 16 日更新
immer 库是当今最好的状态管理库之一