How is the actual immutability of state in Redux?
I'm trying to figure out how much immutability is actually (if at all) used in Redux. Every tutorial / article / document I've found states that reducers should never modify the state object, but instead create a new copy of the changed data (i.e., Reducers should be pure functions). I understand this, but I couldn't find a place where there is an explanation of how this guide is actually used by the internal Redux implementation.
Is this just a strong recommendation, or does something inside Redux break if I make the reducers impure?
If it's later, what exactly will break?
I've found several places where Dan says that in some (very rare cases) gearboxes may not be clean, but they are risky (again, without explaining what the risk is).
source to share
Redux, when used with React, usually connects using connect
from react-redux
. Wrapping a component with connect
allows you to subscribe to changes in the redux store by specifying a change handler that is called after the action is dispatched and the reducers are called. When the change handler is called, connect
compares the current state of the store to the new state using an identity comparison ( previousState !== newState
) - this is faster than doing a shallow or deep comparison - and only when the two states are not identical, does the completed component update with setState
. Mutating the state will not directly change the references, which will result in the wrapped component not being re-rendered.
This is how it connect
determines if it should call setState:
if (!pure || prevStoreState !== storeState) {
this.hasStoreStateChanged = true
this.setState({ storeState })
}
connect
also provides the ability to override this behavior by specifying that the wrapped component is not clean, using:
connect(mapStateToProps, mapDispatchToProps, mergeProps, {pure: false} )
Identity comparison is also used by pure components when implementing shouldComponentUpdate
to prevent unnecessary calls render
.
TL; DR: the component wrapped in connect
will not be re-rendered if the store state changes due to mutation.
Edit: Nothing in Redx itself will break as it is so minimal it doesn't try to check the state returned by the reducers.
source to share