Reputation: 2168
I have the following selector:
const getAllAddresses = (withStartEnd) =>
createSelector(
[getAllAddressesSelector, getStartAddressSelector, getEndAddressSelector],
(all, startAddress, endAddress) => {
if (!withStartEnd) return [...Object.values(all)];
return [startAddress, ...Object.values(all), endAddress];
}
);
I noticed that the selector is re-calculating every time, event when all
, startAddress
and endAddress
do not change. If I remove the input for the selector function, to something like this:
const getAllAddresses = (
createSelector(
[getAllAddressesSelector, getStartAddressSelector, getEndAddressSelector],
(all, startAddress, endAddress) => {
return [startAddress, ...Object.values(all), endAddress];
}
)
);
Then everything works as expected and the selector does not re-calculate on every call. Seems like I missing something in the selector concept. Any help would be much appreciated.
Upvotes: 3
Views: 7704
Reputation: 18664
Update:
Please refer to How do I create a selector that takes an argument?
In short: the way you did it, will work only if you pass static arguments and create a factory function outside of mapStateToProps
. For dynamic arguments it's more complex and please follow the resource I already mentioned above.
The reason your selector is recalculated each time mapStateToProps
is called is that calling getAllAddresses
will create a new instance of createSelector
and the memoization won't work.
Original answer:
In short, reselect
determines input selector changes, based on identity check ===
.
Therefore, if your input selectors always create and return a new object or array, then your selector will be recalculated each time.
In order to fix the recalculation issues:
From the reselect
docs:
Why is my selector recomputing when the input state stays the same? (please follow the link, there are great examples)
Check that your memoization function is compatible with your state update function (i.e. the reducer if you are using Redux). For example, a selector created with createSelector that recomputes unexpectedly may be receiving a new object on each update whether the values it contains have changed or not. createSelector uses an identity check (===) to detect that an input has changed, so returning a new object on each update means that the selector will recompute on each update.
Upvotes: 3