人人都会AI编程

Redux Toolkit(RTK):现代 Redux 标准写法

更新时间:2026-07-11

Redux Toolkit(简称 RTK)是 Redux 官方推荐的标准工具集,旨在解决传统 Redux 使用中“配置繁琐、样板代码多、容易出错”的痛点。它提供了简化的 API,让开发者可以更高效地编写可维护的状态管理逻辑,并且内置了 Immer、Redux Thunk、Redux DevTools 扩展等最佳实践。

为什么需要 RTK:传统 Redux 的痛点

传统 Redux 需要手动编写 action 类型常量、action creator 函数、reducer 中的 switch/case 逻辑,还要通过中间件(如 redux-thunk)处理异步,配置 Store 时也要组合多个 reducer、应用中间件。这些都导致代码量大且分散,新手容易犯错。

例如,一个简单的计数器在传统 Redux 中需要这样写:

// 1. 定义 action 类型
const INCREMENT = 'counter/increment';
const DECREMENT = 'counter/decrement';

// 2. 编写 action creator
function increment() { return { type: INCREMENT }; }
function decrement() { return { type: DECREMENT }; }

// 3. 编写 reducer
const initialState = { value: 0 };
function counterReducer(state = initialState, action) {
  switch (action.type) {
    case INCREMENT: return { value: state.value + 1 };
    case DECREMENT: return { value: state.value - 1 };
    default: return state;
  }
}

// 4. 配置 store
const rootReducer = combineReducers({ counter: counterReducer });
const store = createStore(rootReducer, applyMiddleware(thunk));

而 RTK 通过 createSliceconfigureStore 将上述步骤大幅简化,代码量减少 50% 以上,且类型推导更友好(配合 TypeScript)。

RTK 核心 API 与标准开发模式

1. configureStore:一行创建 Store

configureStore 替代了 createStore,自动组合多个 reducer、默认启用 Redux DevTools、内置 redux-thunk 中间件,还提供了更清晰的 middleware 配置。

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './features/counter/counterSlice';

const store = configureStore({
  reducer: {
    counter: counterReducer,
    // 其他 slices 的 reducer
  },
});

export default store;

2. createSlice:消灭手写 action 和 reducer

createSlice 会自动生成 action creator 和对应的 reducer 逻辑,你只需要定义初始状态和同步的 reducer 函数。内部基于 Immer 库,允许你“直接修改”状态(实际上是生成不可变更新),代码更自然。

import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment(state) {
      state.value += 1;   // 看似直接修改,实际被 Immer 转为不可变操作
    },
    decrement(state) {
      state.value -= 1;
    },
    incrementByAmount(state, action) {
      state.value += action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

使用 createSlice 后,你无需再定义 action 类型常量,counterSlice.actions.increment() 返回的 action 对象会自动包含 type: 'counter/increment',payload 自动映射。

3. createAsyncThunk:处理异步请求

createAsyncThunk 简化了异步 action 的编写,自动生成 pendingfulfilledrejected 三种 action,你可以在 slice 的 extraReducers 中处理这些状态。这样避免了过去用 thunk 时手动 dispatch 多个 action 的繁琐。

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import axios from 'axios';

// 创建异步 thunk
export const fetchUserById = createAsyncThunk(
  'users/fetchById',
  async (userId) => {
    const response = await axios.get(`/api/users/${userId}`);
    return response.data; // 作为 fulfilled action 的 payload
  }
);

const usersSlice = createSlice({
  name: 'users',
  initialState: { entities: [], loading: 'idle', error: null },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchUserById.pending, (state) => {
        state.loading = 'loading';
      })
      .addCase(fetchUserById.fulfilled, (state, action) => {
        state.loading = 'idle';
        state.entities.push(action.payload);
      })
      .addCase(fetchUserById.rejected, (state, action) => {
        state.loading = 'idle';
        state.error = action.error.message;
      });
  },
});

createAsyncThunk 的第一个参数是 action 类型前缀,第二个是异步执行函数。它返回的 thunk 可以直接 dispatch,例如 dispatch(fetchUserById(123))

4. RTK Query:一站式数据获取与缓存

RTK Query 是 Redux Toolkit 附加的数据获取和缓存方案,类似于 React Query 或 SWR,但深度集成 Redux 状态管理。它通过定义 API endpoint 来自动生成 React hooks,让你在组件中调用即可获得加载、错误、数据等状态,并且自动管理缓存、重复请求去重、乐观更新等。

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const apiSlice = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: (builder) => ({
    getUsers: builder.query({ query: () => '/users' }),
    getUserById: builder.query({ query: (id) => `/users/${id}` }),
    addUser: builder.mutation({
      query: (newUser) => ({ url: '/users', method: 'POST', body: newUser }),
    }),
  }),
});

export const { useGetUsersQuery, useGetUserByIdQuery, useAddUserMutation } = apiSlice;

在组件中直接使用这些 hooks,RTK Query 会自动处理数据的加载与更新,并可与 Redux Store 共享状态。

项目中推荐的使用结构

典型的 RTK 项目结构(基于官方推荐模式):

src/
  app/
    store.js          // 配置 store
  features/
    counter/
      counterSlice.js // 状态切片
    users/
      usersSlice.js
      usersAPI.js     // 如果用 RTK Query
  components/...

这种组织方式让每个功能模块的状态、reducer、异步逻辑都放在一起,便于维护。

React 组件中的使用

通过 react-redux 提供的 useSelector 读取状态,useDispatch 派发 action。

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

function Counter() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <button onClick={() => dispatch(decrement())}>-</button>
      <span>{count}</span>
      <button onClick={() => dispatch(increment())}>+</button>
    </div>
  );
}

RTK 带来的实质变化

  • 代码量锐减:不再需要手动编写 action 类型、creator 和冗长的 switch。
  • 安全性提升:Immer 让不可变更新不出错,内置了序列化检查等开发期警告。
  • 异步管理统一createAsyncThunk 规范了异步处理流程,告别散落的 dispatch。
  • 性能优化开箱即用configureStore 默认启用 Redux DevTools 和开发环境检查。
  • 类型推导优秀:配合 TypeScript,slice 自动推导 state 类型和 action 类型。

何时选用 RTK

当你的应用具有以下特征时,RTK 是一个理想选择:

  • 全局状态较多且复杂(20+ 个全局状态变量)
  • 需要严格的单向数据流和清晰的状态变更历史(可时间旅行调试)
  • 需要丰富的中间件支持(日志、持久化、副作用管理)
  • 团队熟悉 Redux 模式或需要可预测的状态管理架构

对于简单应用,轻量的 Zustand 或 Jotai 可能更合适,但在中大型企业与复杂项目中,RTK 提供的规范化和工具链能显著降低维护成本,是 Redux 官方认证的现代标准写法。