Skip to main content

Types of State Management

Types of state management refer to different tools and patterns used to manage application state across frontend frameworks.

Each tool provides a different way to store state, update state, share state, and keep UI predictable.

Types of State Management = Different patterns and libraries for handling shared app state

One-line idea: Types of State Management = Redux, MobX, Context API, Vuex, NgRx, and Zustand solve shared state using different patterns.

Core Concepts​

Why It Matters​

As applications grow, multiple components may need access to the same state.

Different frameworks and applications solve this problem using different state management tools.

Common examples:

  • Redux for predictable global state
  • MobX for observable reactive state
  • Context API for React shared data
  • Vuex for Vue centralized state
  • NgRx for Angular Redux-style state
  • Zustand for simple lightweight React state
Same goal -> manage shared state
Different tools -> different style and architecture

Main Types​

ToolMain Idea
ReduxCentral store, actions, reducers, dispatch
MobXObservable state, actions, computed values, reactions
Context APIShare React data without prop drilling
VuexCentralized state management for Vue
NgRxRedux-inspired RxJS state management for Angular
ZustandSimple lightweight store for React

Practical Examples​

Redux​

Redux is a state management library based on a centralized store.

The store holds the application state tree.

The only way to change state is by dispatching an action.

Redux = Store + Action + Reducer + Dispatch

Redux: Redux Store​

A store holds the whole state tree of the application.

It is the central place where global state lives.

Store = Central container for application state

The state inside the store changes only when an action is dispatched and processed by the reducer.

A Redux store is not a class.

It is an object with a few methods.

Redux: Redux Action​

An action is a plain JavaScript object with a type field.

It describes what happened in the application.

{
type: "ADD_TO_CART";
}

Actions may also contain extra data called payload.

{
type: "ADD_TO_CART",
payload: {
id: 1,
title: "Headphone"
}
}

Actions describe the event, but they do not describe how state changes.

Redux: Redux Reducer​

Reducers are functions that receive the current state and an action, then return the next state.

(state, action) => newState

Example:

const initialState = {
count: 0,
};

function reducer(state = initialState, action) {
switch (action.type) {
case "INCREMENT":
return {
count: state.count + 1,
};

default:
return state;
}
}

Reducers are responsible for deciding how the application state changes.

Redux: Redux Dispatch​

dispatch(action) sends an action to the store.

This is the only way to trigger a state change in Redux.

dispatch({
type: "INCREMENT",
});

After dispatch, Redux calls the reducer with the current state and the given action.

The reducer returns the next state.

dispatch action -> reducer runs -> new state is calculated

Redux: Redux Subscribe​

subscribe() adds a listener that runs whenever an action is dispatched.

Inside the callback, getState() can be used to read the latest state.

store.subscribe(() => {
console.log(store.getState());
});

This is useful when something needs to react after the state changes.

MobX​

MobX is a reactive state management library.

It uses observables to track changing application state.

MobX = Observable state + actions + computed values + reactions

MobX: MobX Observable​

Observables are state containers in MobX.

They represent application state that can change over time.

The observable annotation can also be called as a function to make an entire object observable.

Observable = State that MobX can track

MobX: MobX Actions​

An action is any piece of code that modifies state.

Actions usually happen in response to an event.

Examples:

  • button clicked
  • input changed
  • WebSocket message arrived
Action = Code that changes observable state

MobX: MobX Computed Values​

Computed values derive information from other observables.

They update automatically when the observables they depend on change.

Computed values are cached and recalculated only when necessary.

Computed = Derived value from observable state

MobX: MobX Reactions​

Reactions perform side effects in response to state changes.

They run whenever the observables they depend on change.

Reaction = Side effect that runs when observed state changes

MobX flow:

Action changes Observable
Observable updates Computed
Observable notifies Reaction
Reaction performs side effect

Context API​

Context API is built into React.

It allows a parent component to make data available to any component in the tree below it without manually passing props through every level.

Context API = Share data across React component tree without prop drilling

Context API: Problem It Solves​

Normally, data is passed from parent to child using props.

But passing props can become verbose when many intermediate components do not need the data.

App -> UserCreate -> Field
App -> UserCreate -> Button

If Field and Button need shared data, the parent may need to pass props through intermediate components.

Context avoids this.

Context API: Context Flow​

Instead of passing props through each component:

Parent -> Child -> Grandchild

Context allows:

Provider -> Any consumer below it

This makes shared data easier to access in deeply nested components.

Context API: Context Example​

Create context.

import { createContext } from "react";

export const UserContext = createContext();

Provide context.

function App() {
const user = "Aman";

return (
<UserContext.Provider value={user}>
<UserCreate />
</UserContext.Provider>
);
}

Consume context.

import { useContext } from "react";
import { UserContext } from "./UserContext";

function Field() {
const user = useContext(UserContext);

return <p>{user}</p>;
}

Now the child component can access the value without receiving it through every parent as props.

Vuex​

Vuex is a state management pattern and library for Vue.js applications.

It provides a centralized store for all components in the application.

Vuex = Centralized state management for Vue applications

Vuex uses a single state tree.

That means one object contains all application-level state and acts as the single source of truth.

Vuex: Vuex State​

Vuex state stores application-level data in one central place.

State = Single source of truth

Components render based on this state.

Vuex: Vuex Actions​

Actions are similar to mutations, but they do not directly mutate the state.

Instead, actions commit mutations.

Actions can also contain asynchronous operations.

Action -> commit mutation

Actions are triggered using:

store.dispatch("actionName");

Vuex: Vuex Mutations​

Mutations are the only way to actually change state in a Vuex store.

Each mutation has:

  • a string type
  • a handler function
Mutation = Predictable state change in Vuex

Vuex flow:

Vue Component -> dispatch action
Action -> commit mutation
Mutation -> changes state
State -> component re-renders

NgRx​

NgRx Store is an RxJS-powered global state management solution for Angular applications.

It is inspired by Redux.

NgRx = Redux-style state management for Angular using RxJS

It is a controlled state container designed to help write performant and consistent Angular applications.

NgRx: NgRx Actions​

Actions describe unique events dispatched from components and services.

Action = Something happened in the Angular application

NgRx: NgRx Reducers​

Reducers are pure functions that handle state changes.

They take the current state and the latest action to compute a new state.

Reducer = Current state + action -> new state

NgRx: NgRx Selectors​

Selectors are pure functions used to select, derive, and compose pieces of state.

Components use selectors to get the state they need.

Selector = Read and derive data from store state

NgRx: NgRx Effects​

Effects handle external interactions and long-running tasks.

Examples:

  • fetching data
  • long-running operations
  • tasks that produce multiple events
  • interactions that components do not need to know directly
Effect = Handles side effects outside components

NgRx flow:

Component -> Action
Action -> Reducer -> Store
Selector -> Component
Action -> Effect -> Service

Zustand​

Zustand is a lightweight state management library for React.

It uses a create method to create a store.

Zustand = Simple store using create and set

The set function is used to access and update state.

Zustand: Zustand Example​

import { create } from "zustand";

const useStore = create((set) => ({
count: 1,

inc: () =>
set((state) => ({
count: state.count + 1,
})),
}));

function Counter() {
const { count, inc } = useStore();

return (
<div>
<span>{count}</span>

<button onClick={inc}>one up</button>
</div>
);
}

In this example:

  • useStore is the custom hook
  • count is the state
  • inc updates the state
  • set applies the state update

Comparison Table​

FeatureReduxMobXContext APIVuexNgRxZustand
FrameworkReact ecosystemJavaScript appsReactVueAngularReact
Main ideaCentral store with reducersObservable reactive stateShared context treeCentral Vue storeRedux-style Angular storeSimple store hook
State updateDispatch actionAction modifies observableProvider value changesMutation changes stateAction + reducerset updates state
Side effectsUsually handled separatelyReactionsComponent logicActions can be asyncEffectsStore functions
Best fitPredictable global stateReactive state updatesAvoiding prop drillingVue app stateAngular app stateSimple lightweight React state

When to Use Which​

NeedGood Option
React app with simple shared dataContext API
React app needing lightweight shared stateZustand
Large React app needing predictable global stateRedux
Reactive observable-style stateMobX
Vue application centralized storeVuex
Angular global state with effects and selectorsNgRx

Summary​

Types of State Management = Redux, MobX, Context API, Vuex, NgRx, and Zustand solve shared state using different patterns.

Redux -> dispatch action, reducer updates store
MobX -> observable changes, reactions run
Context API -> provider shares data down the tree
Vuex -> actions commit mutations to state
NgRx -> actions, reducers, selectors, effects
Zustand -> create store, update with set