Redux Toolkit
Manage complex app state with Redux Toolkit - slices, createAsyncThunk, RTK Query, and the modern Redux approach without boilerplate.
skill: Redux Toolkit category: Web Development tags: [Redux, Redux Toolkit, State Management, React, RTK Query] readingTime: 7
Redux Toolkit is not vanilla Redux - it eliminates the boilerplate (action creators, switch/case reducers, manual Immer) while keeping Redux's predictability and DevTools. Use RTK for apps with complex state logic, many developers, or strict auditability requirements. For simpler apps, Zustand is more ergonomic.
Workflow
- Create slices with createSlicecreateSlice generates action creators and the reducer from a single object - eliminating 70% of classic Redux boilerplate.
- Handle async with createAsyncThunkcreateAsyncThunk generates pending/fulfilled/rejected actions automatically - no manual loading state management.
- Configure the storeconfigureStore sets up Redux DevTools, redux-thunk middleware, and combines slices - one function replaces combineReducers + applyMiddleware + composeWithDevTools.
- Use RTK Query for server stateRTK Query is built into Redux Toolkit - handles data fetching, caching, and invalidation with the same DevTools support.
- Normalize with createEntityAdapterStoring arrays of entities by ID prevents O(n) searches and simplifies CRUD operations on collections.
Output Format
RTK setup: createSlice for state + reducers, createAsyncThunk for async, configureStore, RTK Query for API calls, createEntityAdapter for collections.
createSlice → reducer + actions
createAsyncThunk → pending/fulfilled/rejected
configureStore({ reducer: { slice1, slice2, [api.reducerPath]: api.reducer } })
createApi → typed query/mutation hooksExamples
Input
Output
Edge Cases & Gotchas
- Selector memoization - useSelector runs on every store update. Use createSelector (reselect) to memoize expensive derived data - prevents expensive recalculations.
- Middleware order matters - Custom middleware must be added before or after the default middleware. getDefaultMiddleware() returns [thunk, serializabilityCheck, ...] - insert correctly.
- Immer in reducers only - RTK's Immer is only active inside createSlice reducers. Direct mutation outside a reducer still causes bugs.
- RTK Query cache and manual invalidation - RTK Query caches are tag-based. Forgetting to add providesTags or invalidatesTags causes stale UI after mutations.
When to Break These Rules
- Use Zustand for smaller apps or teams that find Redux's structure too restrictive.
- Use TanStack Query instead of RTK Query if you're not using Redux for anything else - TanStack Query has a better API for non-Redux projects.
Reference Files
https://redux-toolkit.js.org/https://redux-toolkit.js.org/rtk-query/overview