Loading Redux Flow

Initializing editors and state...

Redux FlowExamples ↓Understand

Understand Redux,
one step at a time.

Interact with any control below. Every dispatched action walks through the Redux cycle in the panel on the right — step by step, at your pace.

Controls — dispatch actions here

counterSlice

state.counter.value

0

userSlice

state.user

○ logged out

todosSlice

state.todos.items[]

0 active
  • empty — add one above

cartSlice

state.cart.items

  • 📘

    Redux Handbook

    $29

  • 🧰

    RTK Starter Kit

    $19

  • 🔷

    TypeScript Guide

    $24

  • ⚛️

    React Patterns

    $34

createAsyncThunk

pending → fulfilled | rejected

idleloadingsuccesserror

Watch the action log → async/fetchUser/pending fires instantly, then fulfilled or rejected after ~1.4s.

Action Composer

Manually build and dispatch any action to the store

Quick actions

Subscription Map

Subscription Map

Which component re-renders when each slice changes

Components

Counter
UserProfile
TodosPanel
CartPanel
AsyncPanel

Slices

state.counter
state.user
state.todos
state.cart
state.async

Only the component subscribed to the changed slice re-renders. Others are skipped by React-Redux equality check.

20 Examples

basic → advanced
click run → to dispatch live
01
Dispatch with no payloaddispatch · action

Simplest form — the reducer knows what to do without any extra data.

basic
02
Decrementdispatch · action

Same zero-payload pattern, opposite direction.

basic
03
Reset to initialStateinitialState

Reducer replaces the current value with the hardcoded initialState.

basic
04
Logout — wipe object statestate reset

Sets every field back to its initial value in one action.

basic
05
Add todo — string payloadarray · push

A string becomes the payload. Reducer constructs a new object and pushes it.

basic
06
Clear completed todosarray · filter

No payload needed. Reducer replaces the array with a filtered copy.

basic
07
Set view filterenum payload

Payload is a union string. Controls which items the UI renders.

basic

Core Concepts

Store

Single source of truth. configureStore() composes your slices into one state tree.

Slice

RTK bundle of initialState + reducers + action creators for one feature.

Reducer

(state, action) → newState. Pure function. Immer lets you write mutations safely.

Action

Plain object: { type, payload? }. Describes what happened, not how to change state.

dispatch()

Sends an action through middleware → reducers → subscribers. Returns the action.

Selector

fn(state) → value. Component re-renders only when the selected value changes.

Middleware

Intercepts every dispatch. Runs between dispatch() and reducers. Powers thunks, logging.

createAsyncThunk

Wraps async work. Auto-dispatches /pending, /fulfilled, /rejected lifecycle actions.

extraReducers

Lets a slice react to actions from other slices or async thunks via builder.addCase().

How Action Names Are Generated

Redux Toolkit action type formula

type = sliceName/reducerName (or thunkPrefix/lifecycle)

createSlice({ name: 'counter' })

dispatch(increment())

counter/increment

Increment comes from the reducer key increment in counterSlice.

createSlice({ name: 'todos' })

dispatch(addTodo('Learn RTK'))

todos/addTodo

Payload carries the todo text, but payload is not part of the action type string.

createSlice({ name: 'cart' })

dispatch(setQuantity({ id: 2, qty: 3 }))

cart/setQuantity

Object payload still maps to one stable type, so reducers can match quickly.

createSlice({ name: 'user' })

dispatch(login({ name, email }))

user/login

The slice name user namespaces all user actions to avoid collisions.

createAsyncThunk('async/fetchUser', ...)

dispatch(fetchUser({ id: 1, fail: false }))

async/fetchUser/pending then fulfilled|rejected

Thunk lifecycle actions are generated automatically by Redux Toolkit.

createAction('@@timeTravel/load')

dispatch(loadSnapshot(snapshot))

@@timeTravel/load

Manual action type string: useful for cross-slice global actions.

Where Each Action Goes

1. Component dispatches

Buttons and handlers call dispatch(actionCreator(payload)).

2. Middleware chain runs

Thunk/default middleware runs first, then flowLoggerMiddleware records prevState and nextState.

3. Root reducer routes by type

configureStore reducer map sends counter/* to counterSlice, user/* to userSlice, and so on.

4. Matching case reducer updates state

createSlice reducer key matches action.type and Immer applies immutable updates.

5. Subscribers/selectors re-check

useAppSelector compares selected values; only affected components re-render.

6. FlowVisualizer displays the trip

flowEvents receives action + state snapshots so you can see exactly what changed.