React State Management: useState vs useReducer vs Context vs Zustand

React State Management: useState vs useReducer vs Context vs Zustand

React state management is not a single tool — it’s a spectrum from local component state to global app state, and picking the wrong layer creates unnecessary complexity. useState for simple local state, useReducer for complex local state, Context for configuration, Zustand for app-wide state.

TL;DR: useState for simple primitive/object local state. useReducer when next state depends on previous in complex ways. Context for global config/theme/auth (not high-frequency updates). Zustand for global state with frequent updates — simpler than Redux, more capable than Context.

useState — simple local state

// Simple state: use useState
function Counter() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');
  // Independent pieces of state — separate useState calls
  return ;
}

// Object state: OK for related values
function Form() {
  const [form, setForm] = useState({name:'',email:'',age:''});
  const update = field => e =>
    setForm(prev=>({...prev,[field]:e.target.value}));
  return (
    <>
      
      
    
  );
}

useReducer — complex state transitions

// Use when: multiple sub-values, next state depends on previous
const initialState = { status:'idle', data:null, error:null };

function reducer(state, action) {
  switch(action.type) {
    case 'FETCH_START':   return {...state, status:'loading', error:null};
    case 'FETCH_SUCCESS': return {status:'success',data:action.payload,error:null};
    case 'FETCH_ERROR':   return {...state, status:'error', error:action.error};
    case 'RESET':         return initialState;
    default: throw new Error('Unknown action: '+action.type);
  }
}

function DataFetcher({url}) {
  const [state, dispatch] = useReducer(reducer, initialState);
  useEffect(() => {
    dispatch({type:'FETCH_START'});
    fetch(url).then(r=>r.json())
      .then(data=>dispatch({type:'FETCH_SUCCESS',payload:data}))
      .catch(err=>dispatch({type:'FETCH_ERROR',error:err.message}));
  }, [url]);
}

Context — global config, not frequent state

// GOOD: Context for slow-changing global values
const ThemeContext = createContext('light');
const AuthContext = createContext(null);

// BAD: Context for frequent updates (every update re-renders all consumers)
// Don't use Context for: shopping cart (updated on every add/remove)
// Do use Context for: theme, locale, auth user, feature flags

function App() {
  const [theme, setTheme] = useState('light');
  return (
    
      
    
  );
}

// Consume:
const {theme} = useContext(ThemeContext);

Zustand — simple global state

import {create} from 'zustand';

// Define store
const useCartStore = create((set,get) => ({
  items: [],
  total: 0,
  addItem: (item) => set(state => ({
    items: [...state.items, item],
    total: state.total + item.price
  })),
  removeItem: (id) => set(state => ({
    items: state.items.filter(i=>i.id!==id),
    total: state.total - (state.items.find(i=>i.id===id)?.price||0)
  })),
  clear: () => set({items:[],total:0})
}));

// Use in any component (no Provider needed!)
function CartIcon() {
  const {items} = useCartStore();
  return {items.length};
}
  • ✅ useState: primitive values, independent state pieces
  • ✅ useReducer: multiple related values, complex transitions
  • ✅ Context: slow-changing global (theme, auth, locale)
  • ✅ Zustand: global state with frequent updates — simpler than Redux
  • ❌ Don’t use Context for high-frequency updates — all consumers re-render
  • ❌ Don’t install Redux for small apps — overkill, Zustand is simpler

External reference: Zustand documentation.

Recommended Reading

Designing Data-Intensive Applications — The bible of distributed systems and production engineering at scale.

The Pragmatic Programmer — Timeless engineering wisdom every senior developer needs.

Affiliate links. We earn a small commission at no extra cost to you.

Free Weekly Newsletter

🚀 Join 2,000+ Senior Developers

Get expert-level JavaScript, Python, AWS, system design and AI secrets every week. Zero fluff, pure signal.

✓ No spam✓ Unsubscribe anytime✓ Expert-level only

Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply