Redux 入门指南
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
Redux 是一个用于实现可预测、可维护的全局状态管理的 JavaScript 库。
它能帮助你构建行为一致、可在不同环境(客户端、服务器和原生应用)中运行且易于测试的应用程序。此外,它还提供了卓越的开发体验,例如支持时间旅行调试的实时代码编辑功能。
你可以将 Redux 与 React 或任何其他视图库配合使用。它体积小巧(仅 2kB,含依赖项),但拥有丰富的插件生态系统。
Redux Toolkit 是我们官方推荐的 Redux 逻辑编写方案。它封装了 Redux 核心,包含构建 Redux 应用必备的工具包和函数。Redux Toolkit 内置了我们建议的最佳实践,能简化大多数 Redux 任务,避免常见错误,让 Redux 应用开发更加轻松。
RTK 提供的工具可简化多种常见场景,包括 store 配置、 创建 reducer 和编写不可变更新逻辑, 甚至能一次性创建完整的状态切片。
无论你是刚接触 Redux 的新用户正在创建第一个项目,还是希望简化现有应用的经验丰富的开发者, Redux Toolkit 都能帮助你优化 Redux 代码。
安装
Redux Toolkit
可通过 NPM 安装 Redux Toolkit 包,适用于模块打包工具或 Node 应用:
# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit
创建新的 Redux 项目
使用 Redux 创建新应用的推荐方式是采用我们的官方模板。这些模板已预先配置好 Redux Toolkit,并包含一个小型示例应用帮助你快速上手。
要创建新项目,你可以使用类似 tiged 的工具来克隆并提取模板。
# Vite + TypeScript
npx tiged reduxjs/redux-templates/packages/vite-template-redux my-app
# Create React App + TypeScript
npx tiged reduxjs/redux-templates/packages/cra-template-redux-typescript my-app
# Create React App + JavaScript
npx tiged reduxjs/redux-templates/packages/cra-template-redux my-app
# Expo + TypeScript
npx tiged reduxjs/redux-templates/packages/expo-template-redux-typescript my-app
# React Native + TypeScript
npx tiged reduxjs/redux-templates/packages/react-native-template-redux-typescript my-app
# Standalone Redux Toolkit App Structure Example
npx tiged reduxjs/redux-templates/packages/rtk-app-structure-example my-app
除了我们的官方模板之外,社区也创建了其他模板,例如 Next.js with-redux 模板。
# Next.js + Redux
npx create-next-app --example with-redux my-app
Redux 核心库
可通过 NPM 安装 Redux 核心库,适用于模块打包工具或 Node 应用:
# NPM
npm install redux
# Yarn
yarn add redux
该包包含预编译的 ESM 构建版本,可直接在浏览器中作为 <script type="module"> 标签使用。
更多详情请参阅安装指南。
基础示例
应用的整个全局状态存储在单个 store 内部的对象树中。 改变状态树的唯一方式是创建描述发生了什么事的 action 对象,并将其 dispatch 到 store。 为了定义状态如何响应 action 更新,你需要编写纯函数 reducer ,根据旧状态和 action 计算新状态。
Redux Toolkit 简化了编写 Redux 逻辑和配置 store 的过程。使用 Redux Toolkit 时,基础应用逻辑如下:
import { createSlice, configureStore } from '@reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0
},
reducers: {
incremented: state => {
// 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
state.value += 1
},
decremented: state => {
state.value -= 1
}
}
})
export const { incremented, decremented } = counterSlice.actions
const store = configureStore({
reducer: counterSlice.reducer
})
// Can still subscribe to the store
store.subscribe(() => console.log(store.getState()))
// Still pass action objects to `dispatch`, but they're created for us
store.dispatch(incremented())
// {value: 1}
store.dispatch(incremented())
// {value: 2}
store.dispatch(decremented())
// {value: 1}
不同于直接修改状态,你可以通过名为 action 的普通对象来描述所需的变化。随后编写一个称为 reducer 的特殊函数,决定每个 action 如何转换整个应用程序的状态。
在典型的 Redux 应用中,只有一个 store 和一个根 reducer 函数。随着应用规模增长,你可以将根 reducer 拆分为多个独立操作状态树不同部分的小型 reducer。这就像 React 应用中只有一个根组件,但它由众多小组件构成一样。
对于计数器应用来说,这种架构可能显得复杂,但此模式的美妙之处在于它能完美扩展到大型复杂应用。同时它支持强大的开发者工具,因为可以追溯每次状态变更到触发它的 action。你可以录制用户会话并通过重放每个 action 来复现完整过程。
Redux Toolkit 让我们能够编写更简洁、更易读的逻辑,同时完全遵循 Redux 的行为模式和数据流。
传统示例
作为对比,原始 Redux 的传统语法(无抽象层)如下所示:
import { createStore } from 'redux'
/**
* This is a reducer - a function that takes a current state value and an
* action object describing "what happened", and returns a new state value.
* A reducer's function signature is: (state, action) => newState
*
* The Redux state should contain only plain JS objects, arrays, and primitives.
* The root state value is usually an object. It's important that you should
* not mutate the state object, but return a new object if the state changes.
*
* You can use any conditional logic you want in a reducer. In this example,
* we use a switch statement, but it's not required.
*/
function counterReducer(state = { value: 0 }, action) {
switch (action.type) {
case 'counter/incremented':
return { value: state.value + 1 }
case 'counter/decremented':
return { value: state.value - 1 }
default:
return state
}
}
// Create a Redux store holding the state of your app.
// Its API is { subscribe, dispatch, getState }.
let store = createStore(counterReducer)
// You can use subscribe() to update the UI in response to state changes.
// Normally you'd use a view binding library (e.g. React Redux) rather than subscribe() directly.
// There may be additional use cases where it's helpful to subscribe as well.
store.subscribe(() => console.log(store.getState()))
// The only way to mutate the internal state is to dispatch an action.
// The actions can be serialized, logged or stored and later replayed.
store.dispatch({ type: 'counter/incremented' })
// {value: 1}
store.dispatch({ type: 'counter/incremented' })
// {value: 2}
store.dispatch({ type: 'counter/decremented' })
// {value: 1}
学习 Redux
我们提供多种资源帮助您学习 Redux。
Redux 核心教程
Redux 核心教程采用"自上而下"的教学方式,通过我们最新推荐的 API 和最佳实践指导"如何正确使用 Redux"。建议从这里开始学习。
Redux 基础教程
Redux 基础教程采用"自下而上"的教学方式,从基本原理出发,不依赖任何抽象层,讲解"Redux 如何工作"及标准使用模式的形成原因。
学习现代 Redux 直播
Redux 维护者 Mark Erikson 在"与 Jason 一起学习"节目中讲解了当前推荐的 Redux 使用方式。直播包含实时编码示例,演示了如何在 TypeScript 中使用 Redux Toolkit 和 React-Redux 钩子,以及全新的 RTK Query 数据获取 API。
访问“学习现代 Redux”节目笔记页面获取文字记录和示例应用源代码链接。
其他教程
-
Redux 仓库包含多个示例项目,展示 Redux 的各种用法。几乎所有示例都有对应的 CodeSandbox 沙盒环境,这是可在线上操作的交互式代码版本。完整示例列表参见**示例页面**。
-
Redux 创建者 Dan Abramov 在 Egghead.io 上的免费视频课程《Redux 入门》 和 《使用 Idiomatic Redux 构建 React 应用》
-
Redux 维护者 Mark Erikson 的**会议演讲"Redux 基础"** 和 研讨会幻灯片"Redux 基础"
-
Dave Ceddia 的文章《Redux 初学者完全教程》
其他资源
-
**Redux 常见问题解答了许多 Redux 使用中的常见疑问,“使用 Redux”文档章节**则包含处理派生数据、测试、组织 reducer 逻辑和减少样板代码的信息。
-
Redux 维护者 Mark Erikson 的 《Practical Redux》教程系列 展示了 React 与 Redux 结合使用的中高级实战技巧(该系列也可作为 Educative.io 上的互动课程 访问)。
-
React/Redux 资源列表 包含分类整理的专题文章,涵盖 reducer 与 selector、副作用管理、Redux 架构与最佳实践 等内容。
-
社区已创建数千个 Redux 相关库、插件和工具。《生态系统》文档页 列出了我们的推荐清单,完整目录可查阅 Redux 插件目录。
帮助与讨论
Reactiflux Discord 社区 的 #redux 频道 是官方学习资源,解答所有 Redux 相关问题。Reactiflux 是交流技术、提问学习的绝佳平台——欢迎加入!
您也可在 Stack Overflow 使用 #redux 标签 提问。
如需报告错误或提交反馈,请在 GitHub 仓库提交 issue。
是否应该使用 Redux?
Redux 是管理状态的有效工具,但您仍需评估其是否适合当前场景。切勿仅因他人推荐而使用 Redux——请充分考量其潜在优势与取舍。
以下情况建议使用 Redux:
-
应用随时间推移会产生合理规模的状态变化
-
需要单一可信数据源
-
发现顶级组件已无法有效管理全部状态
关于 Redux 适用场景的深度思考: