Implement Zustand State Selectors in React to Prevent Unneeded Rerenders

Daishi Kato
InstructorDaishi Kato
Share this video with your friends

Social Share Links

Send Tweet
Published 3 years ago
Updated 3 years ago

We have to functions right now. createStore that creates module state and useStore that consumes the module state that we created.

The logic is working as expected. State is being properly shared to the components that need it while still isolated from the rest of the app. The issue now is that we have extra re-renders in our application. Each component will rerender when any state changes

To fix this, we'll implement a selector function that will peek the value that you need out of state. This way only the components that depend on the value that is changed will re-render.

Daishi Kato: [0:00] We have created store function to create a store with a module state, and we have used store hook to use the store. They are library code. In application code, we create a store with two properties, count one and count two.

[0:16] There is counter one component to use count one property. The component shows the count number and the button to increment the count number. The inc-one function is to call setState with an updating function. Counter two component is the same component, except that it's for count two property.

[0:37] Finally. we have app component to show two components for each. This works as expected, but there are some extra re-renders. To reveal it naively, let's put must Math.random in the counter components. This is generally not recommended because Math.random is not a pure function. Now, you can see components re-render without updating count numbers.

[1:04] Let's improve our useStore hook to avoid these extra re-renders. We use a selector function, which takes a state value and returns an arbitrary derived value. Typically, selector is used to pick a property of an object. If you don't specify a selector function, it defaults to the identity function. Then, the selector is used right after getting the state.

[1:31] Notice we add the selector to the useEffect dependency array. Now, with the modified useStore hook, we pass a selector function in the Counter1 component. We wrap the selector function with useCallback to make it stable because it's used in the dependency array in useStore. Even if you forget to wrap it, it will still work.

[1:56] The value we get from the useStore hook is now the count1 value instead of the whole state object. Apply the same change in the Counter2 component. It should be ready to check the behavior. If you click the button in the Counter1 area, it doesn't affect the Counter2 area, and vice versa.

[2:20] Let's recap our modification in the useStore hook. It takes a selector function in the second argument and applies it to the state value. When the selector function is changed, it will resubscribe to the store. Re-subscription is very lightweight, but it's usually idiomatic to wrap a selector function with useCallback.

egghead
egghead
~ an hour ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today