Skip to content

🧠 State Management

The Senior Mindset: Every piece of state has a cost. A senior engineer distinguishes between Global State (shared across the app), Local State (contained in one component), and Server Cache (mirrored data from an API). The best state management strategy is often the one that stores the least amount of data globally.


🏛️ 1. Unidirectional Data Flow (Redux, Vuex)

Section titled “🏛️ 1. Unidirectional Data Flow (Redux, Vuex)”

The “Strict” architecture. Inspired by the Flux pattern, it ensures that state changes are explicit and traceable.

  • How it works: Action ⮕ Dispatcher ⮕ Store ⮕ View. You never mutate state directly; you dispatch an action that a Reducer uses to calculate a new state.
  • Pros: Predictable, excellent debugging (Time-travel debugging), and easy to test business logic.
  • Cons: High boilerplate (“Ceremony”). You often need many files just to update a single boolean.

🍃 2. Atomic & Modular State (Zustand, Pinia)

Section titled “🍃 2. Atomic & Modular State (Zustand, Pinia)”

The modern evolution. These libraries strip away the boilerplate while keeping the benefits of a central store.

  • Zustand (React): A small, fast, and scalable state management solution using hooks. It doesn’t require a “Provider” wrapping your app, which avoids unnecessary re-renders.
  • Pinia (Vue): The successor to Vuex. It is intuitive, supports Hot Module Replacement, and has native TypeScript support.
  • Pros: Extremely low boilerplate, high developer velocity, and easy to split into “stores” (e.g., useUserStore, useCartStore).

The current “frontier” of state management (Solid.js, Preact, Angular, Vue).

  • How it works: Instead of a component re-rendering because an object changed, a Signal is a wrapper around a value. When the value changes, the Signal surgically updates only the specific DOM nodes or computations that “subscribed” to it.
  • Pros: Performance is incredible. It eliminates the “Virtual DOM Diffing” overhead for state updates.
  • Cons: Requires a different mental model (you are dealing with “references” to values rather than the values themselves).

PatternExamplesBest ForComplexity
Flux / ReduxRedux Toolkit, VuexMassive teams, highly complex state transitions.High
Hooks / StoresZustand, PiniaMost modern web apps, rapid development.Low
AtomsRecoil, JotaiApps with complex, cross-dependent state pieces.Moderate
SignalsSvelte, Solid, AngularPerformance-critical apps, high-frequency updates.Low/Moderate

1. The “Server State” vs. “UI State” Split

Section titled “1. The “Server State” vs. “UI State” Split”

A common senior mistake is putting API data in Redux/Zustand.

  • Senior Move: Use React Query (TanStack Query) or SWR for server data. These handle caching, revalidation, and loading states automatically. Use your state manager (Zustand/Pinia) only for true UI state (e.g., “Is the sidebar open?”, “Current theme”).

Avoid nested objects in your store. If you have a list of posts, each with an array of comments, it’s hard to update.

  • Strategy: Store them like a database: posts: { [id]: post } and comments: { [id]: comment }. Use IDs to link them. This makes updates $O(1)$ and prevents data inconsistency.

Never store data in the state that can be calculated from other data.

  • Example: Don’t store totalPrice. Store the items array and use a Selector (like reselect or a computed property) to calculate the total. This ensures the total is always “in sync” and avoids “dual source of truth” bugs.

💡 Seniority Note: Before reaching for a library, ask: “Can I solve this with a simple Prop Drill or the Context API?” For many apps, the built-in tools are sufficient. Only introduce a state management library when the complexity of passing data between distant components becomes a bottleneck for development.


  • [[Frontend-Frameworks-Architecture]]
  • [[Optimization-Web-Performance]]
  • [[Backend-API-Design]]