v5.0.0-rc.0
Pre-releaseThis release candidate switches createSelector
to use weakMapMemoize
as the default memoization method, adds a resultEqualityCheck
option to weakMapMemoize
, reworks the dev mode check setup and adds a dev-mode check for result functions that look like x => x
, and makes some final types tweaks. This has breaking changes.
See the preview Redux Toolkit 2.0 + Redux core 5.0 Migration Guide for an overview of breaking changes in RTK 2.0 and Redux core.
npm install reselect@next
yarn add reselect@next
Changelog
createSelector
Uses weakMapMemoize
By Default
Reselect's createSelector
originally only had one memoization function, which has always called defaultMemoize
. It's always used a customizable comparison method to compare each argument. Over time, we added more functionality, particularly in v4.1.0 where defaultMemoize
gained options for {memoize, maxSize, resultEqualityCheck}
.
However, defaultMemoize
has limitations. The biggest one is that the default cache size is 1. This makes selector instances hard to reuse in scenarios like list items, which might call selectSomeValue(state, props.id)
, and thus never actually memoize due to changing arguments. There are workarounds, but they're cumbersome - using createSelectorCreator
to create a customized createSelector
function with a different memoization implementation, creating unique selector instances per component, or setting a fixed maxSize
.
For 5.0, we added a new weakMapMemoize
memoization function, which takes a different approach. It uses an internal tree of cache nodes rather than a single value or a list of values. This gives weakMapMemoize
an effectively infinite cache size!
We've done a fair amount of testing, and weakMapMemoize
both performs faster and has more frequent cache hits than defaultMemoize
.
Given that, we've made the switch so that createSelector
uses weakMapMemoize
by default! This should result in better performance for Redux and React apps that use Reselect.
This is hopefully a mostly non-breaking change at the code level, and an overall improvement at the behavior level.
This is a breaking change. weakMapMemoize
does not have an equalityCheck
option or allow customizing the comparison behavior - it's entirely based on reference comparisons, since it uses WeakMap/Map
internally. It also does not have a maxSize
option, but does have resultEqualityCheck
.
If you need to customize the overall equality comparison behavior, import and pass defaultMemoize
as the memoize
and argsMemoize
option!
Also, since defaultMemoize
is no longer the actual "default" memoization function, we are considering a potential rename of defaultMemoize
to something like lruMemoize
to clarify the naming.
Dev-Mode Checks
Earlier, we added an inputStabilityCheck
that checked for input selectors that accidentally return new references, with a globally exported override method.
In this release, we've added an additional dev mode check that looks for result functions that look like x => x
- in other words, passing the input function result straight through. This is almost always a logic error. Either the input selectors are doing too much work, or the selector is just performing a straight lookup with no derived values and it should be a plain function instead of memoized.
Both checks are customizable on a per-selector-instance basis, and also controllable at a global level:
setGlobalDevModeChecks({
inputStabilityCheck: 'always',
identityFunctionCheck: 'never'
})
createSelector(
[input1, input2],
resultFn,
{devModeChecks: {identityFunctionCheck: 'always'}}
)
What's Changed
- Update Docs for v5 changes. by @aryaemami59 in #636
- V5 final type changes by @aryaemami59 in #639
- Match
resetRecomputations
andresetDependencyRecomputations
behavior to their types by @aryaemami59 in #646 - Try adding
resultEqualityCheck
toweakMapMemoize
by @markerikson in #647 - Make
EqualityFn
slightly more type-safe. by @aryaemami59 in #651 - Switch createSelector to use weakMapMemoize by default by @markerikson in #649
- Add warning in development when a result function is
x => x
. by @aryaemami59 in #645
Full Changelog: v5.0.0-beta.1...v5.0.0-rc.0