intermediate
Selectors
Subscribe to minimal store slices so components re-render only for data they actually use.
Zustand components subscribe via the store hook with a selector: `useStore((s) => s.bears)`. Only when the selected slice changes (shallow by default with selector) does the component re-render.
const bears = useStore((s) => s.bears);
const addBear = useStore((s) => s.addBear); // stable if action reference stable
For multiple fields use shallow compare from `zustand/shallow` or split into two selector calls. Do not select the whole store unless the component truly needs everything.
The trade-off is fine-grained subscriptions versus selector functions recreated each render unless stabilized.
On interviews: compare to Redux useSelector and Context re-render behavior.
Common pitfalls: inline object selectors `(s) => ({ a: s.a, b: s.b })` without shallow compare, deriving new arrays every select causing loops, and subscribing in non-React modules without `subscribe`.
Checklist:
- Select smallest needed projection.
- shallow for object/tuple picks.
- Separate state from actions selectors.
- useStore.subscribe for non-React listeners.