1

I have seen many example codes of redux and found that we use useSelector in mostly 2 ways.

  1. nested
    import React from 'react'
    import { useSelector } from 'react-redux'
    
    export const UserComponent = () => {
      const name = useSelector((state) => state.user.name)
      const age = useSelector((state) => state.user.age)
      return <div>{name}, {age}</div>
    }
  1. non-nested
    import React from 'react'
    import { useSelector } from 'react-redux'
    
    export const UserComponent = () => {
      const user = useSelector((state) => state.user)
      return <div>{user.name}, {user.age}</div>
    }

As you can see, with approach 2, I will end up saving lots of code repetition and I only need to create 1 selector. So I wanted to know the difference, any performance benefits, etc.

Vikram Ray
  • 960
  • 2
  • 10
  • 17
  • It depends on what field you need, if you need many fields from `user` you wouldn't want to create a separate `useSelector` for each, however if you only need 1 or 2 fields like `name` and `age` you may be better off doing it with 2 `useSelector`'s so you can then reference it directly in your component. – Shmili Breuer Jun 02 '21 at 17:38

1 Answers1

2

There is a difference between these two approaches, let's dive deeper into the useSelector hook and see how it works. So let's say you're the creator of this hook and you define it as:

// this is your redux state
const state = { user: { name: 'Haseeb', age: 10 } };

// defining our own selector hook
const useSelector = (selectorFunction) => {
  
  const accessedProperty = selectorFunction(state);

  // accessedProperty will contain whatever is returned from the selectorFunction
  return accessedProperty;
}

Now, let's use our hook

// nested, subscribe to just the name property in user
const name = useSelector((state) => state.user.name);

// non-nested, subscribe to the complete user object
const user = useSelector((state) => state.user);

Talking about the performance, When an action is dispatched, useSelector() will do a reference comparison of the previous selector result value and the current result value. If they are different, the component will be forced to re-render. If they are the same, the component will not re-render.

So in your nested approach, useSelector will only do a reference equality comparison of the name value. AND in your non-nested approach, useSelector will do a reference equality comparison of the complete user object. In both cases, the result of the comparison determines whether the component should re-render. Chances are the non-nested approach will cause more re-renders than the nested approach because the non-nested approach is subscribing to more values than the nested approach.

Call useSelector() multiple times, with each call returning a single field value but it is also okay to use one useSelector() if further performance optimizations are not necessary

Haseeb Anwar
  • 2,438
  • 19
  • 22