Skip to main content

React Redux 快速入门

¥React Redux Quick Start

你将学到什么
  • 如何通过 React Redux 设置和使用 Redux Toolkit

    ¥How to set up and use Redux Toolkit with React Redux

先决条件

介绍

¥Introduction

欢迎来到 React Redux 快速入门教程!本教程将向你简要介绍 React Redux 并教你如何开始正确使用它。

¥Welcome to the React Redux Quick Start tutorial! This tutorial will briefly introduce you to React Redux and teach you how to start using it correctly.

如何阅读本教程

¥How to Read This Tutorial

本页面将重点介绍如何使用 Redux Toolkit 设置 Redux 应用以及你将使用的主要 API。有关 Redux 是什么、它如何工作以及如何使用 Redux Toolkit 的完整示例的说明,请参阅 Redux 核心文档教程

¥This page will focus on just how to set up a Redux application with Redux Toolkit and the main APIs you'll use. For explanations of what Redux is, how it works, and full examples of how to use Redux Toolkit, see the Redux core docs tutorials.

在本教程中,我们假设你同时使用 Redux Toolkit 和 React Redux,因为这是标准的 Redux 使用模式。这些示例基于 典型的 Create-React-App 文件夹结构,其中所有应用代码都在 src 中,但这些模式可以适应你正在使用的任何项目或文件夹设置。

¥For this tutorial, we assume that you're using Redux Toolkit and React Redux together, as that is the standard Redux usage pattern. The examples are based on a typical Create-React-App folder structure where all the application code is in a src, but the patterns can be adapted to whatever project or folder setup you're using.

Create-React-App 的 Redux+JS 模板 附带了已配置的相同项目设置。

¥The Redux+JS template for Create-React-App comes with this same project setup already configured.

使用总结

¥Usage Summary

安装 Redux 工具包和 React Redux

¥Install Redux Toolkit and React Redux

将 Redux Toolkit 和 React Redux 包添加到你的项目中:

¥Add the Redux Toolkit and React Redux packages to your project:

npm install @reduxjs/toolkit react-redux

创建 Redux 存储

¥Create a Redux Store

创建一个名为 src/app/store.js.txt 的文件。从 Redux Toolkit 导入 configureStore API。我们首先创建一个空的 Redux 存储并将其导出:

¥Create a file named src/app/store.js. Import the configureStore API from Redux Toolkit. We'll start by creating an empty Redux store, and exporting it:

app/store.js
import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
reducer: {},
})

这将创建一个 Redux 存储,并自动配置 Redux DevTools 扩展,以便你可以在开发时检查该存储。

¥This creates a Redux store, and also automatically configure the Redux DevTools extension so that you can inspect the store while developing.

为 React 提供 Redux Store

¥Provide the Redux Store to React

创建存储后,我们可以通过在 src/index.js 中的应用周围放置 React Redux <Provider> 来使其可供我们的 React 组件使用。导入我们刚刚创建的 Redux store,在 <App> 周围放置 <Provider>,并将 store 作为 prop 传递:

¥Once the store is created, we can make it available to our React components by putting a React Redux <Provider> around our application in src/index.js. Import the Redux store we just created, put a <Provider> around your <App>, and pass the store as a prop:

index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import store from './app/store'
import { Provider } from 'react-redux'

// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))

root.render(
<Provider store={store}>
<App />
</Provider>,
)

创建 Redux 状态切片

¥Create a Redux State Slice

添加一个名为 src/features/counter/counterSlice.js.txt 的新文件。在该文件中,从 Redux Toolkit 导入 createSlice API。

¥Add a new file named src/features/counter/counterSlice.js. In that file, import the createSlice API from Redux Toolkit.

创建切片需要一个用于标识切片的字符串名称、一个初始状态值以及一个或多个用于定义如何更新状态的化简器函数。创建切片后,我们可以导出生成的 Redux action Creators 和整个切片的 reducer 函数。

¥Creating a slice requires a string name to identify the slice, an initial state value, and one or more reducer functions to define how the state can be updated. Once a slice is created, we can export the generated Redux action creators and the reducer function for the whole slice.

Redux 需要 我们通过制作数据副本并更新副本来不变地写入所有状态更新。然而,Redux Toolkit 的 createSlicecreateReducer API 在内部使用 伊梅尔 来允许我们 编写 "mutating" 更新逻辑,使其成为正确的不可变更新

¥Redux requires that we write all state updates immutably, by making copies of data and updating the copies. However, Redux Toolkit's createSlice and createReducer APIs use Immer inside to allow us to write "mutating" update logic that becomes correct immutable updates.

features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'

export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: (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.
// Also, no return statement is required from these functions.
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
},
},
})

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer

将切片 Reducer 添加到存储

¥Add Slice Reducers to the Store

接下来,我们需要从计数器切片导入 reducer 函数并将其添加到我们的存储中。通过在 reducer 参数内定义一个字段,我们告诉存储使用此切片缩减器函数来处理对该状态的所有更新。

¥Next, we need to import the reducer function from the counter slice and add it to our store. By defining a field inside the reducer parameter, we tell the store to use this slice reducer function to handle all updates to that state.

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

export default configureStore({
reducer: {
counter: counterReducer,
},
})

在 React 组件中使用 Redux 状态和操作

¥Use Redux State and Actions in React Components

现在我们可以使用 React Redux 钩子让 React 组件与 Redux 存储交互。我们可以使用 useSelector 从存储中读取数据,并使用 useDispatch 调度操作。创建一个 src/features/counter/Counter.js 文件,其中包含 <Counter> 组件,然后将该组件导入到 App.js 中并在 <App> 中渲染它。

¥Now we can use the React Redux hooks to let React components interact with the Redux store. We can read data from the store with useSelector, and dispatch actions using useDispatch. Create a src/features/counter/Counter.js file with a <Counter> component inside, then import that component into App.js and render it inside of <App>.

features/counter/Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
import styles from './Counter.module.css'

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

return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
)
}

现在,任何时候你单击 "增量" 和“递减”按钮:

¥Now, any time you click the "Increment" and "Decrement buttons:

  • 相应的 Redux action 将被调度到 store

    ¥The corresponding Redux action will be dispatched to the store

  • 计数器切片 reducer 将看到操作并更新其状态

    ¥The counter slice reducer will see the actions and update its state

  • <Counter> 组件将从存储中看到新的状态值,并使用新数据重新渲染自身

    ¥The <Counter> component will see the new state value from the store and re-render itself with the new data

你学到了什么

¥What You've Learned

这是关于如何通过 React 设置和使用 Redux Toolkit 的简要概述。回顾细节:

¥That was a brief overview of how to set up and use Redux Toolkit with React. Recapping the details:

概括
  • 使用 configureStore 创建 Redux 存储

    ¥Create a Redux store with configureStore

    • configureStore 接受 reducer 函数作为命名参数

      ¥configureStore accepts a reducer function as a named argument

    • configureStore 自动设置存储并具有良好的默认设置

      ¥configureStore automatically sets up the store with good default settings

  • 向 React 应用组件提供 Redux 存储

    ¥Provide the Redux store to the React application components

    • <App /> 周围放置一个 React Redux <Provider> 组件

      ¥Put a React Redux <Provider> component around your <App />

    • 将 Redux 存储作为 <Provider store={store}> 传递

      ¥Pass the Redux store as <Provider store={store}>

  • 使用 createSlice 创建 Redux "slice" reducer

    ¥Create a Redux "slice" reducer with createSlice

    • 使用字符串名称、初始状态和命名化简器函数调用 createSlice

      ¥Call createSlice with a string name, an initial state, and named reducer functions

    • Reducer 函数可以使用 Immer "mutate" 状态

      ¥Reducer functions may "mutate" the state using Immer

    • 导出生成的切片 reducer 和动作创建器

      ¥Export the generated slice reducer and action creators

  • 在 React 组件中使用 React Redux useSelector/useDispatch 钩子

    ¥Use the React Redux useSelector/useDispatch hooks in React components

    • 使用 useSelector 钩子从存储中读取数据

      ¥Read data from the store with the useSelector hook

    • 使用 useDispatch 钩子获取 dispatch 函数,并根据需要分派操作

      ¥Get the dispatch function with the useDispatch hook, and dispatch actions as needed

完整的计数器应用示例

¥Full Counter App Example

以下是运行 CodeSandbox 时的完整 Counter 应用:

¥Here's the complete Counter application as a running CodeSandbox:

下一步是什么?

¥What's Next?

我们建议你阅读 Redux 核心文档中的 "Redux 要点" 和 "Redux 基础知识" 教程,这将使你完整了解 Redux 的工作原理、Redux Toolkit 和 React Redux 的作用以及如何正确使用它。

¥We recommend going through the "Redux Essentials" and "Redux Fundamentals" tutorials in the Redux core docs, which will give you a complete understanding of how Redux works, what Redux Toolkit and React Redux do, and how to use it correctly.