Context API & State Mgmt

Global State Management

As your app grows, you’ll need to share state across many components. Here’s how to choose the right tool.

When to Use What

Solution Best for Complexity
useState Local component data None
Context API Low-frequency globals (theme, auth, locale) Low
Zustand Medium apps โ€” minimal boilerplate Low
Redux Toolkit Large apps with complex state & devtools Medium
TanStack Query Server state (API data, caching) Low

Zustand โ€” Minimal Global Store

npm install zustand
// store/useCartStore.js
import { create } from "zustand";

const useCartStore = create((set, get) => ({
  items: [],
  total: 0,

  addItem: (product) => set(state => {
    const exists = state.items.find(i => i.id === product.id);
    return {
      items: exists
        ? state.items.map(i => i.id === product.id ? { ...i, qty: i.qty + 1 } : i)
        : [...state.items, { ...product, qty: 1 }],
      total: state.total + product.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),
  })),

  clearCart: () => set({ items: [], total: 0 }),
  itemCount: () => get().items.reduce((n, i) => n + i.qty, 0),
}));

// No Provider needed โ€” use in any component
function CartBadge() {
  const count = useCartStore(s => s.items.length); // subscribe to slice
  return <span className="badge">{count}</span>;
}

function AddToCartButton({ product }) {
  const addItem = useCartStore(s => s.addItem);
  return <button onClick={() => addItem(product)}>Add to Cart</button>;
}

Redux Toolkit (RTK) โ€” Enterprise Scale

npm install @reduxjs/toolkit react-redux
// store/counterSlice.js
import { createSlice } from "@reduxjs/toolkit";

const counterSlice = createSlice({
  name: "counter",
  initialState: { value: 0 },
  reducers: {
    increment: state => { state.value += 1; },  // Immer lets you "mutate" directly
    decrement: state => { state.value -= 1; },
    setTo:     (state, action) => { state.value = action.payload; },
  },
});

export const { increment, decrement, setTo } = counterSlice.actions;
export default counterSlice.reducer;

// store/index.js
import { configureStore } from "@reduxjs/toolkit";
export const store = configureStore({ reducer: { counter: counterReducer } });

// main.jsx
import { Provider } from "react-redux";
<Provider store={store}><App /></Provider>

// In a component
const count    = useSelector(state => state.counter.value);
const dispatch = useDispatch();
<button onClick={() => dispatch(increment())}>+</button>
TipFor most new projects, start with useState + Context for simple globals, and add Zustand if global state gets complex. Reach for Redux Toolkit only when you need time-travel debugging or have a very large team.