There is an article on the Redux website about selector memoization with the Reselect library, where they provide next example:
const state = {
a: {
first: 5
},
b: 10
}
const selectA = state => state.a
const selectB = state => state.b
const selectA1 = createSelector([selectA], a => a.first)
const selectResult = createSelector([selectA1, selectB], (a1, b) => {
console.log('Output selector running')
return a1 + b
})
const result = selectResult(state)
// Log: "Output selector running"
console.log(result)
// 15
const secondResult = selectResult(state)
// No log output
console.log(secondResult)
// 15
Overall this example is clear, except for the selectA1
selector.
Redux docs stated that
When you call the selector, Reselect will run your input selectors with all of the arguments you gave, and looks at the returned values. If any of the results are === different than before, it will re-run the output selector, and pass in those results as the arguments.
So, if we provide state.a
, which is object, as an input selector for selectA1
, it will fail ===
check and run a => a.first
every time, right? Or have I misunderstood something?
So, if we provide
state.a
, which is object, as an input selector forselectA1
, it will fail===
check and runa => a.first
every time, right?
No, an object reference will always be strictly equal to itself.
The selectA
selector function returns state.a
which is a reference to an object with value { first: 5 }
. state.a
will continue to always be a reference to this object until an action is dispatched to update state.a
to then be a reference to a new object with a value, then the selectA1
selector function will recompute its output value.
I hope this snippet helps illustrate object reference equality.
const state = {
a: { first: 5 },
};
const selectA = state => state.a;
// same reference, true
console.log(selectA(state) === state.a);
// same "value", but false because different reference
console.log({ first: 5 } === state.a);