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 component, 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.
react-redux connected components do a shallow strict equality check to decide if they want to update. see http://redux.js.org/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 components 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 recommend checking out the seamless-immutable or immutable packages for managing state. Also, the reselect library can help you extract memoized objects specific to your component's needs.
the immer library is one of the best state management libraries as of today
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With