⏱️ Estimated read: 4 min
|
🖨️ Print / PDF
|
🔗 Copy Link
A compact reference for the Redux Toolkit series. Tables only, no prose. Use it during slice authoring, store configuration, and component integration.
Quick How-To Guides & Fast Fixes Need a quick fix or step-by-step solution? Browse our fast answers on HowTo.KandZ.me :
Installation
Package Purpose @reduxjs/toolkitCore: configureStore, createSlice, createAsyncThunk react-reduxProvider, useSelector, useDispatch@reduxjs/toolkit/query/reactRTK Query hooks mswNetwork mocking in tests vitest or jestTest runner
Store Setup
Item Syntax Create store configureStore({ reducer: { slice: sliceReducer } })Root state type ReturnType<typeof store.getState>Dispatch type typeof store.dispatchAdd middleware getDefaultMiddleware().concat(custom)Prepend middleware getDefaultMiddleware().prepend(custom)DevTools Enabled by default in development Provider <Provider store={store}>{children}</Provider>
createSlice
Item Syntax Create createSlice({ name, initialState, reducers, extraReducers })Action creators slice.actions.actionNameReducer slice.reducerImmer mutation state.value += 1 (no return needed)Return new state return { ...state, value: 0 }Payload type PayloadAction<T>No payload action: PayloadActionPrepare callback reducers: { add: { reducer, prepare } }
Reducers
Pattern Example Direct mutation state.items.push(action.payload)Filter state.items = state.items.filter((i) => i.id !== action.payload)Find and update const t = state.items.find((i) => i.id === id); if (t) t.done = trueReset return initialStateNested update state.user.profile.name = action.payload
createAsyncThunk
Item Syntax Create createAsyncThunk('typePrefix', payloadCreator)Payload creator async (arg, thunkApi) => { return data }thunkApi.getStategetState()thunkApi.dispatchdispatch(action)thunkApi.rejectWithValuerejectWithValue(errorPayload)Pending action thunk.pending(requestId)Fulfilled action thunk.fulfilled(payload, requestId)Rejected action thunk.rejected(error, requestId)Dispatch dispatch(thunk(arg))Unwrap await dispatch(thunk(arg)).unwrap()
Async Thunk Generics
Parameter Purpose Inferred ReturnedResolved value From payload creator return ThunkArgDispatch argument From first parameter ThunkApiConfigstate, dispatch, extra, rejectValueNo
Config field Purpose stateTypes getState() dispatchTypes thunkApi.dispatch extraTypes thunkApi.extra rejectValueTypes rejectWithValue payload
extraReducers
Builder method Purpose .addCase(actionCreator, reducer)Handle a specific action .addMatcher(matcher, reducer)Handle actions matching a predicate .addDefaultCase(reducer)Handle unmatched actions
extraReducers: (builder) => {
builder
.addCase(fetchTodos.pending, (state) => { state.status = 'loading' })
.addCase(fetchTodos.fulfilled, (state, action) => { state.items = action.payload })
.addCase(fetchTodos.rejected, (state, action) => { state.error = action.error.message })
}
RTK Query
Item Syntax Create API createApi({ reducerPath, baseQuery, endpoints })Base query fetchBaseQuery({ baseUrl })Query endpoint builder.query({ query: (arg) => '/path' })Mutation endpoint builder.mutation({ query: (body) => ({ url, method: 'POST', body }) })Generated hook useGetXQuery, useUpdateXMutationReducer api.reducerMiddleware api.middlewareTag types tagTypes: ['Todo']Invalidate invalidatesTags: ['Todo']Provide tag providesTags: ['Todo']
RTK Query Hooks
Hook field Meaning dataCurrent data isLoadingInitial load, no cache isFetchingRe-fetch in progress isSuccessData is available isErrorRequest failed errorError object refetchManual re-fetch isUninitializedLazy query not triggered
RTK Query Lifecycle
Option Purpose pollingIntervalRe-fetch interval (ms) skipPollingIfUnfocusedPause when tab hidden skipSkip the query refetchOnMountOrArgChangeRe-fetch on mount/arg change keepUnusedDataForCache retention (default 60s) preferCacheValueLazy trigger uses cache
Lazy Queries and Prefetching
Item Syntax Lazy hook const [trigger, result] = useLazyGetXQuery()Trigger trigger(arg)Trigger with cache trigger(arg, true)Prefetch hook const prefetch = usePrefetch('getX')Prefetch call prefetch(arg)Initiate thunk dispatch(api.endpoints.getX.initiate(arg))
TypeScript Hooks
Hook Syntax (React Redux 9.1+) Selector useSelector.withTypes<RootState>()Dispatch useDispatch.withTypes<AppDispatch>()Store useStore.withTypes<RootState>()
Hook Syntax (pre-9.1) Selector useSelector((s: RootState) => ...)Dispatch useDispatch<AppDispatch>()
Pre-typed Thunk Helper
// app/withTypes.ts
import { createAsyncThunk } from '@reduxjs/toolkit'
import type { RootState, AppDispatch } from './store'
export const createAppAsyncThunk = createAsyncThunk.withTypes<{
state: RootState
dispatch: AppDispatch
rejectValue: string
}>()
Item Value Helper createAsyncThunk.withTypes<Config>()Usage createAppAsyncThunk(typePrefix, payloadCreator)Benefit No generics at the call site
Selectors
Pattern Example Basic useAppSelector((state) => state.todos.items)Derived useAppSelector((state) => state.todos.items.filter((t) => !t.completed))Memoized createSelector([inputSelector], (items) => ...)Parameterized (id) => (state) => state.todos.items.find((t) => t.id === id)
Middleware
Item Syntax Signature store => next => action => { ... }Action type guard isAction(action) (RTK 2.0)Add after defaults getDefaultMiddleware().concat(custom)Add before defaults getDefaultMiddleware().prepend(custom)Disable serializability serializableCheck: falseIgnore action paths ignoredActionPaths: ['payload.date']Ignore state paths ignoredPaths: ['cache.entries']
Serializability
Serializable Not serializable undefined, nullDateboolean, number, stringMap, SetPlain object Class instance Array Function PromiseSymbol
Conversion Replacement DateISO string MapPlain object or entries array SetArray Class instance Plain object + selectors Function ID or Server Function reference
Testing Slices
Test Code Initial state reducer(undefined, { type: '@@INIT' })Sync action reducer(state, actionCreator(payload))Thunk pending reducer(state, thunk.pending('req'))Thunk fulfilled reducer(state, thunk.fulfilled(data, 'req'))Thunk rejected reducer(state, thunk.rejected(error, 'req'))Assertion expect(state).toEqual(expected)
Testing Thunks
Step Code Handler http.get('/api/x', () => HttpResponse.json(data))Server setupServer(...handlers)Before all server.listen()After each server.resetHandlers()After all server.close()Store configureStore({ reducer: { slice } })Dispatch await store.dispatch(thunk(arg))Assert state expect(store.getState().slice.status).toBe('idle')Assert value await store.dispatch(thunk()).unwrap()Component await waitFor(() => screen.getByText(...))
File Structure
src/
├── app/
│ ├── store.ts # configureStore + RootState + AppDispatch
│ ├── hooks.ts # useAppSelector, useAppDispatch
│ └── withTypes.ts # createAppAsyncThunk
├── features/
│ └── todos/
│ ├── todosSlice.ts
│ └── todosSlice.test.ts
├── mocks/
│ ├── handlers.ts # MSW handlers
│ └── server.ts # setupServer
└── components/
└── TodoList.tsx
Common Commands
Command Purpose npm install @reduxjs/toolkit react-reduxInstall core packages npm testRun tests npx vitestRun Vitest npx msw init public/Initialize MSW service worker Redux DevTools Browser extension for state inspection
Imports Quick Reference
What Import configureStore@reduxjs/toolkitcreateSlice@reduxjs/toolkitcreateAsyncThunk@reduxjs/toolkitcreateSelector@reduxjs/toolkitisAction@reduxjs/toolkitPayloadAction@reduxjs/toolkitcreateApi@reduxjs/toolkit/query/reactfetchBaseQuery@reduxjs/toolkit/query/reactProviderreact-reduxuseSelectorreact-reduxuseDispatchreact-reduxsetupServermsw/nodehttp, HttpResponsemsw
Keywords
← Previous Redux Toolkit 22 ⚛️ Testing Thunks — Mocking API calls in async thunks
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for: ✅ Finance (Mortgage, Interest, Inflation) ✅ Tech (Base64, JSON, Dev Suite, IP) ✅ Health (BMI, BMR, TDEE) ✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private 🔒 No data leaves your device 💎 100% Free
🔗 Use it now: https://tools.kandz.me 🔖 Bookmark it—you’ll need it later!