Search code examples
javascriptreactjsredux

Is there a performance difference between using useSelector once or multiple times?


I'm basically wondering if there is a difference in performance, or any other pros and cons, between the following 2 code snippets. Are there any objective reasons to use one over the other, or is it just personal preference?

const prop1 = useSelector((state) => state.appModel.prop1);
const prop2 = useSelector((state) => state.appModel.prop2);
const prop3 = useSelector((state) => state.appModel.prop3);
const prop4 = useSelector((state) => state.appModel.prop4);
const {
  prop1,
  prop2,
  prop3,
  prop4,
} = useSelector((state) => ({
  prop1: state.appModel.prop1,
  prop2: state.appModel.prop2,
  prop3: state.appModel.prop3,
  prop4: state.appModel.prop4,
}));

The second option instinctively feels like it might be more performant, because it only uses useSelector once, but then I wonder if one property changing may cause more re-renders because they're all grouped together.

UPDATE:

Also wondering if this even shorter version has any pros and cons?

const { prop1, prop2, prop3, prop4 } = useSelector((state) => state.appModel);

Apologies if this is a duplicate, I tried searching but wasn't entirely sure of the terminology to search for, and couldn't see any matching examples.


Solution

  • The individual one is much better performance wise. Your second approach creates a new object every time the selector is called, so when useSelector compares the before and after it always looks like it has changed. As a result, your component is forced to render on every change to the redux store, even if nothing happened to prop1-prop4.

    If you want to do #2, you need to make a memoized selector, so that it returns the same object if none of the individual values have changed. You can read more about memoized selectors here: https://redux.js.org/usage/deriving-data-selectors#optimizing-selectors-with-memoization

    (While it's good to learn about memoized selectors, for your case i would recommend sticking with approach #1)

    Also wondering if this even shorter version has any pros and cons?

    const { prop1, prop2, prop3, prop4 } = useSelector((state) => state.appModel);

    That's better than #2, because now it will only need to rerender when appModel changes. If the only things in appModel are prop1-prop4, then this will be basically the same as #1. If there are extra properties in appModel that you don't care about, then this may result in a few extra renders when appModel changes due to those other properties.