Skip to main content

State Management

State management = organizing and sharing application state


What is State Management?

"Organizing application data"

State management is the process of organizing, storing, and updating application state in a predictable way.

"State management involves organizing application state, determining where it lives, how it's accessed, and how it's updated across components."


Local State

useState for component-specific data

function Component() {
const [count, setCount] = useState(0);
// Local to this component
}

Use for:

  • Component-specific UI state
  • Form inputs
  • Toggle states

"Local state (useState) is for component-specific data that doesn't need to be shared."


Lifted State

Move state to common ancestor

function App() {
const [user, setUser] = useState(null);
return (
<>
<Header user={user} />
<Profile user={user} />
</>
);
}

"Lifted state is moved to the nearest common ancestor when multiple components need the same state."


Context API

Share state across many components

const UserContext = createContext();

function App() {
const [user, setUser] = useState(null);
return (
<UserContext.Provider value={{ user, setUser }}>
<Components />
</UserContext.Provider>
);
}

Use for:

  • Theme, user, language
  • Shared across many components
  • Not frequently changing

"Context API shares state across many components without prop drilling, good for theme, user, or language."


Redux

Predictable state container

  • Store: Single source of truth
  • Actions: Describe what happened
  • Reducers: Specify how state updates
  • Dispatch: Send actions

"Redux is a predictable state container with a single store, actions, and reducers for managing complex application state."


Redux Pattern

Action → Reducer → Store → View

// Action
const increment = () => ({ type: "INCREMENT" });

// Reducer
function counter(state = 0, action) {
switch (action.type) {
case "INCREMENT":
return state + 1;
default:
return state;
}
}

// Dispatch
dispatch(increment());

"Redux follows unidirectional data flow: actions describe changes, reducers update state, store holds state, components read from store."


Zustand

Lightweight state management

const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));

function Component() {
const { count, increment } = useStore();
}

Simpler than Redux, good for medium complexity.

"Zustand is a lightweight state management library, simpler than Redux, good for medium complexity applications."


When to Use What

Complexity determines solution

ComplexitySolution
Simple, localuseState
Shared, few componentsLifted state
Shared, many componentsContext
Complex, predictableRedux
Medium complexityZustand/Jotai

"Choose state management based on complexity: useState for local, Context for shared, Redux for complex, Zustand for medium."


9️⃣ State Management Principles

Single source of truth · Predictable updates

  • Single source of truth: One place for state
  • Predictable updates: Clear update patterns
  • Immutable updates: Don't mutate state
  • Time travel: Redux DevTools

"State management principles include single source of truth, predictable updates, immutability, and debugging tools."


Best Practices

✅ Start with local state ✅ Lift state when needed ✅ Use Context for shared data ✅ Consider Redux for complex apps ✅ Keep state normalized ✅ Avoid prop drilling ❌ Don't over-engineer


"State management organizes application data. Use useState for local state, lift state for shared data between few components, Context API for data shared across many components, and Redux/Zustand for complex applications. Choose based on complexity - start simple, add complexity only when needed."


🧠 Ultra-Short Cheat Sheet

Local state (useState)
Lifted state
Context API
Redux (complex)
Zustand (lightweight)
Single source of truth
Predictable updates
Choose based on complexity