Skip to content

Redux

Predictable state container with a strict unidirectional data flow and time-travel debugging.

Web & HTTPState ManagementJavaScript

What it is

Redux is a predictable state container for JavaScript apps. It helps manage application state in a single store, enabling easier debugging, testing, and predictable behavior across the app.

Redux uses a single store to hold the entire state of the application. State changes are made via actions and handled by pure reducer functions. Middleware can extend Redux with additional capabilities like async actions.

Watch for
Use Redux Toolkit, not hand-written reducers — the old boilerplate is why Redux got its reputation
Licence
MIT

When to use it

The question documentation cannot answer for you — because it cannot recommend something else.

Reach for it when

  • Large applications where many distant components share and mutate the same state
  • You need the DevTools' action log and time-travel debugging to understand what happened
  • A team that benefits from one enforced, explicit pattern for every state change

Look elsewhere when

  • Most of your 'state' is really server data — React Query or SWR handles that far better
  • The application is small; Zustand or plain context is a fraction of the code

Installation

npm install redux

Getting started

The smallest useful thing you can do with it, and what each part means.

Creating a simple store
import { createStore } from 'redux';

const initialState = { count: 0 };
const reducer = (state = initialState, action) => {
  switch(action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
};

const store = createStore(reducer);
console.log(store.getState());
Creates a Redux store with an initial state and a simple reducer that handles an INCREMENT action.
Dispatching actions
store.dispatch({ type: 'INCREMENT' });
console.log(store.getState());
Dispatches an action to update the state and prints the new state.

Advanced usage

Where the library earns its place over a simpler alternative.

Using middleware (Redux Thunk)
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

const asyncAction = () => dispatch => {
  setTimeout(() => {
    dispatch({ type: 'INCREMENT' });
  }, 1000);
};

const store = createStore(reducer, applyMiddleware(thunk));
store.dispatch(asyncAction());
Adds asynchronous action handling using Redux Thunk middleware.
Combining reducers
import { combineReducers, createStore } from 'redux';
const reducerA = (state = 0, action) => action.type === 'A' ? state + 1 : state;
const reducerB = (state = 0, action) => action.type === 'B' ? state + 1 : state;
const rootReducer = combineReducers({ a: reducerA, b: reducerB });
const store = createStore(rootReducer);
Combines multiple reducers into a single root reducer for managing different parts of the state.
Subscribing to state changes
store.subscribe(() => console.log('State updated:', store.getState()));
store.dispatch({ type: 'INCREMENT' });
Registers a listener to run whenever the state changes.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

State not updating as expected
Ensure that reducers return a new state object instead of mutating the existing state.
Middleware not working
Check that middleware is applied correctly using `applyMiddleware` when creating the store.
Dispatching unknown action types
Ensure the action type matches what your reducer is handling.

Best practices

  • Keep state normalized and avoid nested structures when possible.
  • Use action creators to encapsulate action creation logic.
  • Keep reducers pure and free of side effects.
  • Use middleware for async actions instead of placing side effects in reducers.
  • Use Redux DevTools for debugging and inspecting state changes.

Alternatives

Comparable options, and the reason you would pick one over the other.

Background

Why it exists, and what it was reacting to.

Redux was created by Dan Abramov and Andrew Clark in 2015. It was inspired by Flux but simplified the architecture, emphasizing a single immutable state tree and pure reducers. Redux became widely adopted for complex React applications to manage state consistently.