admin管理员组文章数量:1289402
I'm working with Redux and recently ran into a problem where I was adding messages to an array and the Redux state was not issueing a re-render on React. I'm using the react-redux
library for this. Here's an example of the problem I was having:
// State structure
structure: { messages: {}, groups: {} }
// ---
newState = { ...prevState };
newState.messages[action.message.group] = action.message;
return newState;
This was updating the state however it wasn't triggering an update to the react ponent, however replacing newState = { ...prevState }
with newState = JSON.parse(JSON.stringify(prevState))
resolved the issue.
Could anyone explain why this is happening in detail? I was under the impression that the spread operator created a clone of the object and I've never had any problems with it until now.
I'm working with Redux and recently ran into a problem where I was adding messages to an array and the Redux state was not issueing a re-render on React. I'm using the react-redux
library for this. Here's an example of the problem I was having:
// State structure
structure: { messages: {}, groups: {} }
// ---
newState = { ...prevState };
newState.messages[action.message.group] = action.message;
return newState;
This was updating the state however it wasn't triggering an update to the react ponent, however replacing newState = { ...prevState }
with newState = JSON.parse(JSON.stringify(prevState))
resolved the issue.
Could anyone explain why this is happening in detail? I was under the impression that the spread operator created a clone of the object and I've never had any problems with it until now.
Share Improve this question asked Apr 20, 2017 at 2:26 HobbyistHobbyist 16.2k11 gold badges53 silver badges102 bronze badges 2- I think you should use this "Object.assign". without directly replace origin value, because we don't mutate the state in generally. (redux.js/docs/basics/Reducers.html) – Wei Commented Apr 20, 2017 at 2:30
- The spread operator is only a shallow copy, not a deep copy like your serialize/deserialize approach. That could affect things. – ShadowRanger Commented Apr 20, 2017 at 2:45
2 Answers
Reset to default 9react-redux connected ponents do a shallow strict equality check to decide if they want to update. see http://redux.js/docs/faq/ImmutableData.html
The spread operator is like Object.assign and does not deeply clone an object. The reason the JSON thing worked is because you created a whole new object which would pass the strict equality check, however all your ponents would update needlessly because nothing will pass a strict equality check now.
Object.assign({}, ...prevState, ...newState) would create a new top-level object, but it would not create a new object for any objects nested in prevState or newState. However, you would have to carefully update nested objects so as to avoid needless re-renders. This can get tricky for deeply nested objects and arrays.
I'd remend checking out the seamless-immutable or immutable packages for managing state. Also, the reselect library can help you extract memoized objects specific to your ponent's needs.
UPDATE 08/16/2020
the immer library is one of the best state management libraries as of today
The spread operator is monly used to make deep copies of JS objects. When we have nested arrays or nested data in an object, the spread operator makes a deep copy of top-level data and a shallow copy of the nested data. While JSON.parse(JSON.stringify(obj)) will do a deep copy of nested data also.
本文标签: javascriptSpread operator vs JSONparse(JSONstringify()) for immutable objectsStack Overflow
版权声明:本文标题:javascript - Spread operator vs JSON.parse(JSON.stringify(...)) for immutable objects - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741442061a2378980.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论