MENU
createSelector & createDraftSafeSelector
createSelector() allows you to define memoized functions that can compute a value from the state.
When you call a selector (eg. selectSum), Reselect will run ALL your input selectors (eg. selectX) 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. If all of the results of the input selectors are the same as the last time, it will skip re-running the output selector, and just return the cached final result from before.
A memoized selector that uses state => state as an input will force the selector to always recalculate.
For memoization to work across multiple components, you should create a unique instance of the selector per component, so that each instance keeps getting the same arguments consistently. Below, without useMemo() or useCallback(), the output selector will be executed on repeated rendering even when the attribute (eg. value={1}) remains the same. This is because the selector uses the results of another copy of the component (<Sum value={2}/). Also, notice how the selector factory function 'makeSelectSum' is defined.
In addition to a "globalized" selector, you may also use a "localized" selector, which accepts only a piece of the state as an argument, without knowing or caring where that is in the root state.
createDraftSafeSelector() allows you to create selectors that can safely be used inside of createReducer() and createSlice() reducers with Immer-powered mutable logic. All selectors created by entityAdapter.getSelectors() are "draft safe" selectors by default.
'unsafe1' and 'unsafe2' will be of the same value, because the memoized selector was executed on the same object - but safe2 will be different from safe1 (with the updated value of 2), because the safe selector detected that it was executed on a Immer draft object and recalculated using the current value instead of returning a cached value.
const selectSelf = state => state
const unsafeSelector = createSelector(selectSelf, (state) => state.value)
const draftSafeSelector = createDraftSafeSelector(
selectSelf,
(state) => state.value
)
// in your reducer:
state.value = 1
const unsafe1 = unsafeSelector(state)
const safe1 = draftSafeSelector(state)
state.value = 2
const unsafe2 = unsafeSelector(state)
const safe2 = draftSafeSelector(state)