Performance: Zustand for client state
This affects how fast the page responds to user actions and how efficiently the UI updates without unnecessary delays.
import { create } from 'zustand'; const useStore = create(set => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) })); function Counter() { const count = useStore(state => state.count); const increment = useStore(state => state.increment); return ( <div> <button onClick={increment}>Increment</button> <p>{count}</p> </div> ); } export default Counter;
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button> <p>{count}</p> </div> ); } export default Counter;
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Local useState in many components | Multiple updates across components | Multiple reflows per update | Higher paint cost due to many re-renders | [X] Bad |
| Zustand with selective subscriptions | Minimal updates only where needed | Single reflow per update | Lower paint cost with fewer re-renders | [OK] Good |
zustand in a Next.js app?create function with a callback receiving set to update state.create with set and updates state immutably. Others use invalid or non-existent APIs.const useStore = create(set => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) }));
useStore.getState().increment();
console.log(useStore.getState().count);const useStore = create(set => ({
count: 0,
increment() {
this.count += 1;
}
}));this.count += 1 tries to mutate the object directly, which does not update Zustand's internal state.set to update state immutably; direct mutation won't trigger updates.this inside increment does not update Zustand state -> Option B!task (when empty).!task inside the set updater.!task (empty), then calls set to add non-empty task.Pass the test and this pattern moves unknown