useSelector and reselect , which one is performance beneficial
Asked Answered
D

1

9

For memoization/performance consideration, using useSelector with ShallowEqual. Will there be some more benefits for performance optimization using "Reselect/createSelector" option ? Or both the options are same ?

Will have the data as JSON array objects at most of the selectors.

Before writing new selector , would like to consider performance/memoization benefits.

Deterrent answered 1/3, 2021 at 16:35 Comment(4)
Reselect is useful because you can compose selectors and the memoization can prevent expensive selector code from running. The memoization can also prevent needless re renders. What you should consider is maintainable code and with reselect you can write selector logic once and re use it by composing selectors. Here is an example of how I use reselect with react-redux.Few
Thanks. Can it be also achieve same with, useSelector with ShallowEqual (internally would do reference comparision) ? Or there would be some more benefits in ReSelect.Deterrent
Even if you only use reselect for memoization (you shouldn't) then shallowEqual still won't prevent generating new objects even if state didn't change. But you should use it to prevent repeating selector logic. if you code has multiple state.someKey instances then you need to change your code in multiple places when you change the state. This looks trivial but what if your selectors implement complex business logic? Like const selectTotal = createSelector([selectPolicy,selectAge,selectPeriod,...],calculate)Few
means, shallowEqual with useReducer will not prevent re-rendering ?Deterrent
A
9
// Example
const selectAndCompute = (state) => {/*expensive computation*/};

const MyComponent = (props) => {
   const computedData = useSelector(selectAndCompute);
   return '...';
}

useSelector will prevent re-render of MyComponent if the selectAndCompute function computes the same result as last time it got triggered (and it gets triggered every time anything in redux state changes). But, this still requires selectAndCompute to run and compute some result. This computation in itself might be expensive.

So, you can add reselect's createSelector to prevent even the computation done in the selectAndCompute. For example if selectAndCompute depends only on the part of the state state.transactions you can define:

const selectAndCompute = createSelector(
  [(state) => state.transactions], 
  (transactions) => {/*expensive computation*/}
);

Now, only if state.transactions has changed the expensive computation will run, otherwise selectAndCompute will immediately return the previous value. And finally useSelector will then block the re-render, same as it would if reselect was not used.

Alica answered 21/9, 2021 at 19:6 Comment(2)
useSelector docs state that The selector will be called with the entire Redux store state as its only argument. The selector will be run whenever the function component renders (unless its reference hasn't changed since a previous render of the component so that a cached result can be returned by the hook without re-running the selector). Am I missing something from this phrasing? Doesn't it mean that the selector won't be run in case shallowEqual(prevProps, newProps) is truthy?Podophyllin
@AlexandreGomes what you quoted is a different issue. It discusses the behavior when the component rerenders due to other reasons, like component's props being changed, or its state (through useState). Above I discussed the issue of useSelector being triggered from the redux store change.Alica

© 2022 - 2025 — McMap. All rights reserved.