Description
What docs page needs to be fixed?
- Section: Balance Selector Usage
- Page: Deriving Data with Selectors
What is the problem?
Quoting from the docs:
Similarly, don't make every single selector memoized!. Memoization is only needed if you are truly deriving results, and if the derived results would likely create new references every time. A selector function that does a direct lookup and return of a value should be a plain function, not memoized.
// ❌ DO NOT memoize: deriving data, but will return a consistent result const selectItemsTotal = state => { return state.items.reduce((result, item) => { return result + item.total }, 0) } const selectAllCompleted = state => state.todos.every(todo => todo.completed)
What should be changed to fix the problem?
I'd be curious here if opinions differ, but I believe the advice above is misleading. Specifically, I think there are plenty of good times you want reselect
-like memoization even if your selector returns a scalar value.
One big benefit of memoization is that the actual selector computation itself doesn't have to rerun in every component using the selector on every redux action if the inputs haven't changed.
Let's say for example you have 100 <Item />
components currently rendered on screen and 1000 items
in the redux store. Each <Item />
does something like useSelector(selectItemsTotal)
. Without memoization, on every dispatched Redux action you'll end up with 100,000 additions taking place. With memoization, you'll have 1000 additions and 100 equality comparision for memoized selectors which will then opt-out of computation.
As a strawman, I'd potentially change the docs to something like the following:
Similarly, don't make every single selector memoized!. Memoization is only needed if you are truly deriving results or if the derived results would likely create new references every time. A selector function that does a direct lookup and return of a value should be a plain function, not memoized.
// ✅ SHOULD memoize: deriving data, so memoize to avoid pointless recomputations const selectItemsTotal = state => { return state.items.reduce((result, item) => { return result + item.total }, 0) } const selectAllCompleted = state => state.todos.every(todo => todo.completed)