Redux (Redux Toolkit) logo

Redux (Redux Toolkit)

The official, opinionated, batteries-included toolset for efficient Redux development.

npm install redux
61.4K16.4M/weekv5.0.1283.01 KBMIT46 issues
Last updated: 2023-12-24
Star history chart for reduxjs/redux

TL;DR

The industry-standard state management library that enforces a strict unidirectional data flow architecture for predictable behavior.

Modern Redux is built via Redux Toolkit (RTK), which simplifies configuration, reduces boilerplate, and includes powerful data fetching capabilities.

Why Redux Toolkit?

While early Redux was infamous for its verbosity, Redux Toolkit (RTK) has reinvented the experience to be pragmatic and powerful. It remains the safest choice for large teams requiring strict architectural constraints.

  • Batteries Included: RTK comes pre-configured with immer (for immutable updates using mutable syntax), thunk (for async logic), and DevTools connections.
  • Simplified Logic: The createSlice API automatically generates action creators and action types based on your reducers, eliminating the need for separate files and switch statements.
  • RTK Query: A powerful data fetching and caching tool included in the package that eliminates the need for manual loading states and useEffect fetching logic.
  • Unrivaled Debugging: The Redux DevTools Extension offers time-travel debugging, state diffing, and action replays, which are unmatched by most newer libraries.
  • Architectural Consistency: It enforces a "one way to do things" approach, which makes onboarding new developers easier in large organizations compared to unopinionated libraries.

Code Snippet

Redux Toolkit consolidates state logic into "slices".

import { createSlice, configureStore } from '@reduxjs/toolkit'
import { Provider, useDispatch, useSelector } from 'react-redux'

// 1. Define the Slice (State + Reducers + Actions)
const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) => {
      // Immer allows "mutating" logic in reducers
      state.value += 1
    },
    decrement: (state) => {
      state.value -= 1
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload
    },
  },
})

export const { increment, incrementByAmount } = counterSlice.actions

// 2. Configure the Store
const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
})

// 3. Consume in Component
function CounterComponent() {
  const count = useSelector((state) => state.counter.value)
  const dispatch = useDispatch()

  return (
    <div>
      <span>{count}</span>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(incrementByAmount(5))}>Add 5</button>
    </div>
  )
}

In a real application, the store setup would be in a separate file, and you would wrap your app with <Provider store={store}>.

Pros and Cons

No library is perfect; understanding the trade-offs is key to selecting the right tool.

Pros

  • Predictability & Traceability: Because state changes only happen via dispatched actions, tracking down when and why a bug occurred is significantly easier.
  • Ecosystem Maturity: It has the largest ecosystem of middleware, add-ons, and documentation in the React world.
  • RTK Query Integration: You get a world-class data fetching solution (similar to TanStack Query) out of the box, tightly integrated with your global state.

Cons

  • Boilerplate: Even with RTK, setting up a store, slices, and providers requires more code than atomic libraries like Jotai or simple stores like Zustand.
  • Conceptual Complexity: Developers must understand concepts like Dispatch, Reducers, Selectors, and Thunks, which creates a steeper learning curve for juniors.
  • Rigidity: The strict unidirectional flow can feel like "over-engineering" for simple features like a form input or a modal toggle.

Comparison with Other State Management Libraries

The table below outlines the positioning differences between Redux and other popular state management libraries to help you make an informed decision:

LibraryDesign PhilosophyBest ForPain Points
Redux ToolkitStrict Flux
Centralized, event-driven, immutable state updates.
Enterprise Teams
Large-scale apps needing strict patterns and deep debugging capabilities.
Verbosity
Requires more files and setup code than any other modern alternative.
ZustandMinimalist
Simple hook-based store with direct state manipulation.
Most Apps
Projects that need global state without the ritual of Redux.
Structure
Lack of structure can lead to messy stores in very large codebases.
Context APINative
Built-in React dependency injection.
Low-Frequency State
Theming, user sessions, or static configuration.
Performance
Causes re-renders of the entire subtree when value changes; not for complex state.

Ecosystem & Extensions

Redux Toolkit is a "batteries-included" solution, but its ecosystem is vast.

  • RTK Query: Included in Redux Toolkit. Handles data fetching, caching, polling, and optimistic updates.
  • Redux Persist: Persist and rehydrate a Redux store between app launches.
  • Redux-Saga: A library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage. (Note: RTK Query has largely replaced this for data fetching).