跳至主要内容

Redux Toolkit 快速入门

您将学到什么
  • 如何使用 React-Redux 设置和使用 Redux Toolkit
先决条件

简介

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

如何阅读本教程

本页将重点介绍如何使用 Redux Toolkit 设置 Redux 应用程序以及您将使用的主要 API。有关 Redux 的解释、工作原理以及 Redux Toolkit 使用方法的完整示例,请参阅“教程概述”页面中链接的教程

在本教程中,我们假设您将 Redux Toolkit 与 React 一起使用,但您也可以将其与其他 UI 层一起使用。这些示例基于 典型的 Create-React-App 文件夹结构,其中所有应用程序代码都在 src 中,但这些模式可以适应您使用的任何项目或文件夹设置。

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

使用摘要

安装 Redux Toolkit 和 React-Redux

将 Redux Toolkit 和 React-Redux 包添加到您的项目中

npm install @reduxjs/toolkit react-redux

创建 Redux Store

创建一个名为 src/app/store.js 的文件。从 Redux Toolkit 导入 configureStore API。我们将从创建一个空的 Redux store 开始,并将其导出

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

export const store = configureStore({
reducer: {},
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

这将创建一个 Redux store,并自动配置 Redux DevTools 扩展,以便您在开发时检查 store。

将 Redux Store 提供给 React

创建商店后,我们可以通过在 src/index.js 中的应用程序周围放置一个 React-Redux <Provider> 来使其可用于我们的 React 组件。导入我们刚刚创建的 Redux 商店,在 <App> 周围放置一个 <Provider>,并将商店作为道具传递。

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

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

创建 Redux 状态切片

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

创建切片需要一个字符串名称来标识切片,一个初始状态值,以及一个或多个 reducer 函数来定义如何更新状态。创建切片后,我们可以导出生成的 Redux 操作创建者和整个切片的 reducer 函数。

Redux 要求我们以不可变的方式编写所有状态更新,通过复制数据并更新副本。但是,Redux Toolkit 的 createSlicecreateReducer API 在内部使用Immer,允许我们编写“变异”更新逻辑,这将成为正确的不可变更新

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

export interface CounterState {
value: number
}

const initialState: CounterState = {
value: 0,
}

export const counterSlice = createSlice({
name: 'counter',
initialState,
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
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action: PayloadAction<number>) => {
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 添加到商店

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

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

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

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

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

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

features/counter/Counter.js
import React from 'react'
import type { RootState } from '../../app/store'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'

export function Counter() {
const count = useSelector((state: RootState) => 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>
)
}

现在,每当你点击“增加”和“减少”按钮时

  • 相应的 Redux 操作将被派发到商店
  • 计数器切片 reducer 会看到这些 action 并更新其状态
  • <Counter> 组件会从 store 中看到新的状态值,并使用新数据重新渲染自身

你学到了什么

这是关于如何在 React 中设置和使用 Redux Toolkit 的简要概述。回顾一下细节

总结
  • 使用 configureStore 创建 Redux store
    • configureStore 接受一个名为 reducer 的函数作为命名参数
    • configureStore 会自动使用良好的默认设置来设置 store
  • 将 Redux store 提供给 React 应用程序组件
    • 在你的 <App /> 周围放置一个 React-Redux <Provider> 组件
    • 将 Redux store 作为 <Provider store={store}> 传递
  • 使用 createSlice 创建 Redux "切片" reducer
    • 使用字符串名称、初始状态和命名 reducer 函数调用 createSlice
    • reducer 函数可以使用 Immer "修改" 状态
    • 导出生成的切片 reducer 和 action creators
  • 在 React 组件中使用 React-Redux useSelector/useDispatch 钩子
    • 使用 useSelector 钩子从 store 中读取数据
    • 使用 useDispatch 钩子获取 dispatch 函数,并根据需要调度 action

完整的计数器应用程序示例

这里显示的计数器示例应用程序也是

这是完整的计数器应用程序,作为一个运行的 CodeSandbox

下一步是什么?

我们建议你浏览 Redux 核心文档中的“Redux Essentials”和“Redux Fundamentals”教程,这些教程将让你全面了解 Redux 的工作原理、Redux Toolkit 的作用以及如何正确使用它。