Reputation: 67
What if second
(nested object) changes in redux?
If it do shallow comparison it should ignore the change and not re-render.
All the example I see in doc, they are based on a simple object, where shallow compare is ok.
// assume state is: {data: {first : {second { } } }}
const selectData = state => state.data;
const selectSecond = createSelector(
selectData,
data => data
);
Upvotes: 3
Views: 4558
Reputation: 42188
createSelector
uses strict equality (===
), which means that two objects are considered "equal" if and only if they are references to the same object in memory. This the same type of check that React uses when comparing state
or comparing useEffect
dependencies.
Shallow equality means that two objects are equal if all of their properties are strictly equal.
Deep equality means that two objects are equal if their contents are the same, regardless of object references. It is computationally expensive and almost never needed in React or Redux due to the immutable nature of data.
Redux state is considered immutable so you should never have a situation where an object is the same reference in memory but has different contents. Every time that a property changes, you must create a new object. If second
has changed, then first
and data
will be new objects.
What if 'second' (nested object) change in redux? If it do shallow comparison it should ignore the change and not rerender.
You would only have this problem if you made a mutation in your state. As long as your reducer is correct then you will get rerenders whenever state.data
changes because any change at all requires creating a new object.
Here's a few examples of the various equality checks:
state => state
state
is strict equal, shallow equal, and deep equal.
state => ({...state})
state
is shallow equal and deep equal. It is not strict equal because it is a new object.
state => ({...state, nested: {...state.nested}})
state
is deep equal. It is not strict equal or shallow equal because the nested
property is a new object.
state => ({...state, number: 5})
state
has a changed property so it fails all equality checks.
state => {
state.nested.number = 5;
return state;
}
This is the sort of mutation that is not allowed in React or Redux. state
is strict equal because we returned the same state
object. It is also shallow equal because state.nested
is the same object. It is not deep equal (unless the value was 5 before).
state => {
state.nested = 5;
return state;
}
Again this is not allowed. If you mutate a top-level property then state
is strict equal but not shallow equal or deep equal.
Upvotes: 9