Selectors & useShallow
Prevent unnecessary re-renders by selecting only the data your component needs.
What are Selectors?
A selector is a function you pass to your Zustand hook to pick out a specific piece of state. By default, Zustand uses strict equality (===) to compare the return value of your selector with its previous value. If it changes, your component re-renders.
const bears = useStore((state) => state.bears);
The Object Literal Problem
If you need multiple values from the store, you might be tempted to return an object literal from your selector:
const { bears, fish } = useStore((state) => ({ bears: state.bears, fish: state.fish }));
Because JavaScript compares objects by reference, this creates a **new object** every time the store updates. This means your component will re-render every single time *anything* in the store changes, defeating Zustand's performance benefits.
Fixing it with `useShallow`
Zustand provides a useShallow helper to fix this. It tells Zustand to shallow-compare the keys of the object you return, rather than strictly comparing the object reference.
tsx
import { useShallow } from 'zustand/react/shallow';
const { bears, fish } = useStore(
useShallow((state) => ({ bears: state.bears, fish: state.fish }))
);
Now, the component will only re-render if bears or fish actually changes.
Re-render Visualization
In this interactive lab, use the toolbar to update different parts of the store. Watch how components using proper selectors ignore updates they don't care about, while poorly configured components re-render pointlessly.
Without useShallow
Object Literal
With useShallow
Shallow Comparison
Click increaseFish(). The bad component re-renders because it created a new object reference, even though 'bears' didn't change!
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- Selectors allow components to subscribe to specific slices of state.
- Returning object literals from selectors breaks strict equality checks.
- Use
useShallowfromzustand/react/shallowwhen returning objects. - Calling
useStore()without a selector subscribes to all state changes.
Done with this concept?
Mark it complete to track your progress. No login needed.