Skip to main content

Redux Toolkit

Redux Toolkit is the official, opinionated, batteries-included toolset for efficient Redux development. It simplifies the most common Redux use cases and reduces boilerplate code.

Overview

Redux Toolkit (RTK) includes utilities to simplify the most common Redux use cases, including store setup, creating reducers, immutable update logic, and more.

What You'll Learn

Core Concepts

  • Store configuration with configureStore()
  • Slice creation with createSlice()
  • Async logic with createAsyncThunk()
  • Entity management with createEntityAdapter()

Key Benefits

  • Less boilerplate: Write less code to accomplish the same tasks
  • Immutable updates: Built-in Immer integration for easier state updates
  • DevTools integration: Automatic Redux DevTools setup
  • TypeScript support: First-class TypeScript integration

Installation

# NPM
npm install @reduxjs/toolkit react-redux

# Yarn
yarn add @reduxjs/toolkit react-redux

Basic Example

import { configureStore, createSlice } from '@reduxjs/toolkit'

// Create a slice
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => {
state.value += 1
},
decrement: (state) => {
state.value -= 1
}
}
})

// Configure store
const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
})

export const { increment, decrement } = counterSlice.actions
export default store

Key APIs

configureStore()

  • Wraps createStore() with good defaults
  • Automatically sets up Redux DevTools
  • Includes redux-thunk by default
  • Adds development-only middleware

createSlice()

  • Generates action creators and action types
  • Uses Immer for immutable updates
  • Reduces boilerplate significantly

createAsyncThunk()

  • Handles async logic and lifecycle actions
  • Automatically dispatches pending/fulfilled/rejected actions
  • Integrates with extraReducers

createEntityAdapter()

  • Provides standardized way to store collections
  • Includes CRUD utilities
  • Optimizes for normalized state shape

Project Structure

src/
store/
index.js # Store configuration
slices/
authSlice.js # Auth-related state
todosSlice.js # Todos state
userSlice.js # User profile state
components/
hooks/
useAppDispatch.js # Typed dispatch hook
useAppSelector.js # Typed selector hook

Best Practices

  1. Use createSlice for most reducers
  2. Use createAsyncThunk for async logic
  3. Structure slices by feature, not by type
  4. Use TypeScript for better developer experience
  5. Keep state normalized when dealing with collections

Common Patterns

Async Data Fetching

const fetchUsers = createAsyncThunk(
'users/fetchUsers',
async () => {
const response = await api.fetchUsers()
return response.data
}
)

Entity Management

const usersAdapter = createEntityAdapter()
const usersSlice = createSlice({
name: 'users',
initialState: usersAdapter.getInitialState(),
reducers: {
userAdded: usersAdapter.addOne,
userUpdated: usersAdapter.updateOne
}
})

Next Steps

  1. Set up your first store - Configure store with createStore
  2. Create your first slice - Build a simple counter or todo slice
  3. Add async logic - Implement data fetching with createAsyncThunk
  4. Learn advanced patterns - Entity adapters, RTK Query, and more