首页
/ Redux 官方推荐姿势:深入理解 Redux Toolkit 的定位、能力清单与最佳实践

Redux 官方推荐姿势:深入理解 Redux Toolkit 的定位、能力清单与最佳实践

2026-09-04 18:08:37作者:晏闻田Solitary

本篇基于 Redux 仓库中的 Redux Toolkit: Overview 文档,系统梳理 Redux Toolkit(下称 RTK)的定义、设计动机与内置 API 全貌,并结合本仓库的源码注释与 examples/counter 官方示例,帮你掌握"为什么 RTK 是编写 Redux 逻辑的官方标准方式"以及"如何在新项目和存量项目中引入 RTK"。

什么是 Redux Toolkit

Redux Toolkit 是 Redux 官方的、有明确设计倾向(opinionated)的、"电池全含"(batteries-included)的高效 Redux 开发工具集。它的目标就是成为编写 Redux 逻辑的标准方式,官方强烈建议使用它。

它包含两类核心能力:

  • 一系列简化最常见 Redux 用例的实用函数:包括 store 配置(store setup)、定义 reducers、不可变更新(immutable update)逻辑,甚至可以在不手写任何 action creator 或 action type 的情况下,一次性创建整个"切片"(slice)状态;
  • 内置最常用的 Redux 生态插件:如用于异步逻辑的 Redux Thunk 和用于编写 selector 函数的 Reselect,装上即可直接使用,无需再额外安装和接线。

安装方式

Redux Toolkit 以 NPM 包形式提供,可配合模块打包器(module bundler)或直接在 Node 应用中使用:

# NPM
npm install @reduxjs/toolkit

# Yarn
yarn add @reduxjs/toolkit

从本仓库的官方示例可以直接确认当前依赖声明方式,例如 examples/counter/package.json 中声明了 "@reduxjs/toolkit": "^2.1.0",并搭配 react-redux 完成 React 集成。

设计动机:RTK 诞生的三大痛点

Redux 核心库是**刻意保持无倾向(unopinionated)**的——store 如何配置、state 里放什么、reducers 怎么组织,全部由你自己决定。这带来了灵活性,但灵活性并非总是被需要:

有时候我们只想要最简的起步方式,附带合理的开箱即用默认行为;或者在大型应用中反复书写相似代码,希望减少手写的样板代码量。

Redux Toolkit 最初就是为了应对社区对 Redux 的三个常见抱怨而创建的:

  1. "配置一个 Redux store 太复杂了"(Configuring a Redux store is too complicated)
  2. "为了让 Redux 干点有用事,我必须添加一堆包"(I have to add a lot of packages to get Redux to do anything useful)
  3. "Redux 需要太多样板代码"(Redux requires too much boilerplate code)

官方表示,虽然无法解决所有用例,但借鉴 [create-react-appapollo-boost 的"零配置"理念,RTK 提供了一个官方推荐的标准工具组合,处理最常见用例、减少额外决策。

为什么你应该使用 Redux Toolkit

RTK 通过以下方式让编写高质量的 Redux 应用变得更简单、更快速:

  • 内置官方推荐的最佳实践(baking in best practices)
  • 提供良好的默认行为(good default behaviors)
  • 帮助捕获错误(catching mistakes)
  • 允许编写更简单的代码

这些收益适用于所有 Redux 用户,不论技能水平或经验深浅;既可以在新项目开始时引入,也可以作为渐进式迁移(incremental migration)的一部分加入现有项目。

使用 RTK 并非强制

原文档特别强调了一个重要边界:

使用 Redux 不要求必须使用 Redux Toolkit。许多现有应用使用其他 Redux 封装库,或完全"手写" Redux 逻辑,如果你更偏好其他做法,完全可以照旧。

但官方立场非常明确:在 Style Guide 中专门设有 "Use Redux Toolkit for Writing Redux Logic" 一节,声明 RTK 是官方推荐的使用 Redux 的工具集,并建议在编写不可变更新逻辑时使用 Immer(最好作为 RTK 的一部分)。换言之:不强制,但强烈建议所有 Redux 应用使用 RTK

来自源码层的佐证:createStore 已被官方弃用

这一推荐并非停留在文档层面,而是直接写进了本仓库的源码中。查看 src/createStore.ts 可以发现,createStore 函数头上携带了完整的 @deprecated 注释:

/**
 * @deprecated
 *
 * **We recommend using the `configureStore` method
 * of the `@reduxjs/toolkit` package**, which replaces `createStore`.
 *
 * Redux Toolkit is our recommended approach for writing Redux logic today,
 * including store setup, reducers, data fetching, and more.
 * ...
 * `createStore` method from the core `redux` package will not be removed, but we encourage
 * all users to migrate to using Redux Toolkit for all Redux code.
 *
 * If you want to use `createStore` without this visual deprecation warning, use
 * the `legacy_createStore` import instead:
 *
 * `import { legacy_createStore as createStore} from 'redux'`
 */

从源码结构看,可以得出几个确定的实现事实:

  • createStore 不会被移除,功能上仍然可用(在 src/index.ts 中仍正常导出,见第 40-50 行的导出列表);
  • 若希望在编辑器中不显示弃用警告,可改从 redux 包导入 legacy_createStore(定义于 src/createStore.ts,它内部只是转调 createStore);
  • 核心包仍然提供 createStorecombineReducersbindActionCreatorsapplyMiddlewarecompose 等基础 API(见 src/index.ts),但官方建议的新代码入口是 RTK 的 configureStore

What's Included:RTK 内置能力清单

这是原文档信息密度最高的部分,以下按 API 逐项说明(其中 createSelector 来自 Reselect 库的再导出):

API 作用 关键特性
configureStore() 包装 createStore,提供简化的配置选项与良好默认值 可自动合并 slice reducers;自动加入你提供的任意 Redux 中间件;默认包含 redux-thunk;自动启用 Redux DevTools Extension
createReducer() 以"action type → case reducer 函数"的查表形式定义 reducer,替代手写 switch 语句 自动使用 Immer 库,让你可以用普通"可变"代码写更简单的不可变更新,例如 state.todos[3].completed = true
createAction() 为给定 action type 字符串生成 action creator 函数 该函数定义了 toString(),因此可以直接替代 type 常量使用
createSlice() 接受 reducer 函数对象、slice 名称和初始 state 值,自动"切片式"创建状态 一次性生成 slice reducer 及对应的 action creators 与 action types
createAsyncThunk 接受 action type 字符串和返回 Promise 的函数 生成一个 thunk,根据该 Promise 的结果自动 dispatch pending/fulfilled/rejected 三种 action
createEntityAdapter 管理 store 中的规范化(normalized)数据 生成一组可复用的 reducers 和 selectors
createSelector Reselect 库的 memoized selector 工具 由 RTK 再导出,方便直接使用

除这些 API 外,RTK 还包含 RTK Query 数据获取 API:一个专为 Redux 打造的强大数据获取与缓存工具,旨在简化 Web 应用中加载数据的常见场景,消除手写数据获取与缓存逻辑的必要性。

官方示例印证:examples/counter 中的现代 Redux 写法

仓库内的 examples/counter 示例完整演示了上文清单中多个 API 的实际用法,可作为可复制的参考实现。

1. 一步完成的 store 配置:configureStore

examples/counter/src/app/store.js 全部代码只有 8 行:

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

export const store = configureStore({
  reducer: {
    counter: counterReducer
  }
})

这一处调用自动完成了传统 createStore 需要手动组合的全部工作:合并 slice reducer(内部走 combineReducers)、注入 redux-thunk 中间件、开发模式下加入捕获意外 mutation 的守卫中间件、接入 Redux DevTools Extension。

2. 一个文件写完整个 feature:createSlice + createAsyncThunk

examples/counter/src/features/counter/counterSlice.js 展示了 RTK 最核心的价值主张——同步 reducer、action 生成、异步逻辑、selector 全部收敛在一个 slice 文件内:

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { fetchCount } from './counterAPI'

const initialState = {
  value: 0,
  status: 'idle'
}

// thunk 允许执行异步逻辑,可像普通 action 一样 dispatch
export const incrementAsync = createAsyncThunk(
  'counter/fetchCount',
  async amount => {
    const response = await fetchCount(amount)
    // 返回的值成为 fulfilled action 的 payload
    return response.data
  }
)

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  // reducers 字段:定义 reducer 并自动生成关联 action
  reducers: {
    increment: state => {
      // RTK 借助 Immer,可以用"可变"语法写不可变更新:
      // 它检测到 draft state 的变更并生成全新的 immutable state
      state.value += 1
    },
    decrement: state => {
      state.value -= 1
    },
    // 使用 PayloadAction 声明 action.payload 的内容
    incrementByAmount: (state, action) => {
      state.value += action.payload
    }
  },
  // extraReducers 字段:处理本 slice 之外定义的 action,
  // 包括 createAsyncThunk 生成和其他 slice 的 action
  extraReducers: builder => {
    builder
      .addCase(incrementAsync.pending, state => {
        state.status = 'loading'
      })
      .addCase(incrementAsync.fulfilled, (state, action) => {
        state.status = 'idle'
        state.value += action.payload
      })
  }
})

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

// selector:从 state 中取值
export const selectCount = state => state.counter.value

// 也可以手写 thunk,包含同步与异步逻辑
export const incrementIfOdd = amount => (dispatch, getState) => {
  const currentValue = selectCount(getState())
  if (currentValue % 2 === 1) {
    dispatch(incrementByAmount(amount))
  }
}

export default counterSlice.reducer

这段代码印证了概述文档中的几项描述:

  • createSlice 自动生成 action creators:counterSlice.actions 直接导出 incrementdecrementincrementByAmount,无需手写任何 action type 常量或 action creator 函数;
  • Immer 支撑的"可变"语法:源码注释明确写道——"Redux Toolkit allows us to write 'mutating' logic in reducers. It doesn't actually mutate the state because it uses the Immer library, which detects changes to a 'draft state' and produces a brand new immutable state based off those changes";
  • createAsyncThunk 的三态生命周期:示例中通过 incrementAsync.pending / incrementAsync.fulfilledextraReducers 里更新 status 字段,正是概述所述"基于 Promise 生成 pending/fulfilled/rejected action"的实际落地;异步请求本身(模拟 500ms 延迟的 Promise)由 examples/counter/src/features/counter/counterAPI.js 提供。

此外,仓库还提供了 TypeScript 版本的同款示例 examples/counter-ts(含 src/app/store.tssrc/features/counter/counterSlice.ts),以及配套的测试文件如 counterSlice.spec.js,适合作为对照学习材料。

RTK 与 Redux 核心包的关系与演进

结合仓库中 Why Redux Toolkit is How To Use Redux Today 一篇,可以补全 Overview 的语境:

  • RTK 包封装在核心 redux 包之上,包含构建 Redux 应用所必需的 API 方法与常用依赖;
  • 官方立场是:今天编写任何 Redux 逻辑,都应该使用 RTK,核心 redux 包单独使用时"仍可用,但已被视为过时(obsolete)"——其全部 API 也从 @reduxjs/toolkit 再导出,configureStore 覆盖了 createStore 的全部能力并提供更好的默认行为与可配置性;
  • 对于存量应用,官方建议至少先把 createStore 换成 configureStore(开发模式中间件能帮你捕获意外 mutation 和可序列化错误),再逐步把最常用的 reducer 迁移到 createSlice;
  • 理解底层概念仍有价值:仓库保留了 Redux Fundamentals 教程 用零抽象展示 Redux 如何运作,但其定位只是学习工具,最终仍会展示 RTK 如何简化那些手写代码。

继续深入的学习路径

Overview 文档指向的完整 RTK 文档在独立站点上,而本仓库内以下页面可作为配套延伸阅读(均相对仓库根目录):

小结

Redux Toolkit 的本质,是把"社区用多年实践验证过的标准做法"固化进官方工具集:一个 configureStore 解决 store 配置,一个 createSlice 同时解决 reducer、action creator、action type 三件套,createAsyncThunk 收敛异步三态管理,createEntityAdaptercreateSelector 处理规范化数据与派生数据,RTK Query 则接管数据获取与缓存。从 src/createStore.ts 的弃用注释到 examples/counter 的完整示例,仓库源码与官方示例共同印证了同一结论:RTK 依然是"Redux"——单一 store、action 驱动、不可变更新一个不少——只是你为同样结果需要手写的代码大幅减少了

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
981
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384