Local State: useState
function Toggle() {
const [isOn, setIsOn] = useState(false);
return <button onClick={() => setIsOn(!isOn)}>{isOn ? 'ON' : 'OFF'}</button>;
}
Complex Local State: useReducer
function reducer(state, action) {
switch (action.type) {
case 'increment': return { count: state.count + 1 };
case 'decrement': return { count: state.count - 1 };
default: return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>{state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
</div>
);
}
Zustand (Recommended for Most Apps)
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));
function Counter() {
const { count, increment } = useStore();
return <button onClick={increment}>Count: {count}</button>;
}
When to Use What
- useState: Component-local state
- useReducer: Complex local state with multiple transitions
- Context: Theme, auth, locale — rarely-changing global state
- Zustand: Most global state needs (simple, fast, minimal boilerplate)
- Redux Toolkit: Large apps with complex state logic and middleware
Ready to Level Up Your Coding Skills?
Join Coderz Club and learn to code with challenges, battles, and an AI mentor.
Join Coderz Club Free →