本文作者为 360 奇舞团前端开发工程师
阅读本文章前,需要先了解下 redux 的基本概念与用法,Redux Toolkit 是建立在 Redux 基础之上的工具包,因此需要对 Redux 的基本概念有一定的了解,包括 Action、Reducer、Store、Middleware 等。理解 Redux 的工作原理和数据流程有助于更好地理解和使用 Redux Toolkit。
简单复习下 redux 的相关内容,以便我们更容易的认识 Redux Toolkit 带来了哪些便捷~
Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理。可以更好的帮助开发者管理项目的数据与状态。
可以将 Redux 与 React 或其他视图库一起使用。它体小精悍(只有 2kB ,包括依赖),却有很强大的插件扩展生态。是 React 生态系统中非常重要的一部分。
所有的状态都以对象树的方式 (state) 存放于单个 store 中。
唯一改变状态树 (state tree) 的方法是创建 action :一个描述发生了什么的对象,并将其 dispatch 派发给 store。 要指定状态树如何响应 action 来进行更新,你可以编写纯 reducer 函数,这些函数根据旧 state 和 action 来计算新 state。
新的 state 被创建后,对象会自动传递给所有注册了监听器的组件,从而触发组件的重新渲染,使得界面始终保持与当前的 state 对象一致。
Redux
Redux 基本原理流程图
通过以上的回顾与学习,相信大家已经对 Redux 有了一些记忆,下面看下 Redux Toolkit --- 简化 Redux 开发流程的利器
Redux Toolkit 是什么?官方给出的解释是:
Redux Toolkit is the official React UI bindings layer for Redux. It lets your React components read data from a Redux store, and dispatch actions to the store to update state.
为了简化 Redux 的开发流程,Redux Toolkit 应运而生。Redux Toolkit 是一个官方推荐的工具包,旨在简化 Redux 开发流程,减少样板代码,提高开发效率。
Redux Tookit(也称为“RTK”) 是官方的推荐的编写 Redux 逻辑方法。
@reduxjs/toolkit 包封装了核心的 redux 包,包含我们认为构建 Redux 应用所必须的 API 方法和常用依赖。Redux Toolkit 集成了我们建议的最佳实践,简化了大部分 Redux 任务,阻止了常见错误,并让编写 Redux 应用程序变得更容易。
通过以上的介绍,虽然说使用 Redux Toolkit 有自己的使用方法,但是本质还是 Redux!如果今天你要写任何的 Redux 逻辑,你都应该使用 Redux Toolkit 来编写代码
Redux Toolkit 的核心功能在了解 Redux Toolkit 之前,我们首先需要理解状态管理的概念。状态管理是指将应用的状态集中管理,使得状态的变化可以被跟踪和控制。
Redux Toolkit 提供了一些核心功能,其中包括:
@reduxjs/toolkit 包: Redux Toolkit 提供了一个包来集成常用的 Redux 工具和中间件。
createSlice: 通过 createSlice 函数,可以轻松地创建包含 reducer 和 action 的 “slice”。
configureStore: 用于创建 Redux store 的函数,集成了常用的 middleware。
createAsyncThunk: 简化异步操作的创建,使得处理异步逻辑更加方便。
createSelector: 用于创建可记忆化的选择器,提高状态选择的性能。
Redux Toolkit 相比于传统的 Redux 开发方式的优点简化开发流程: Redux Toolkit 提供了一系列工具函数和模块,可以大大简化 Redux 的开发流程,减少样板代码。
减少样板代码: 通过使用 createSlice 和 createAsyncThunk,相比于 redux 可以减少大量的重复代码,使得代码更加简洁清晰。
提高开发效率: Redux Toolkit 提供了一套标准化的工具和模式,使得开发者可以更加专注于业务逻辑的实现,提高开发效率,和使用redux相比,大大降低了书写状态管理时出现的失误。
与现有 Redux 生态的兼容性: Redux Toolkit 与传统的 Redux 应用和中间件兼容,可以无缝集成到现有项目中,同时也支持 Redux DevTools 调试工具的使用。
Redux Toolkit?安装
安装和配置 Redux Toolkit 包 --- @reduxjs/toolkit
创建store
- export const store = configureStore({
-
- reducer: {
-
- counter: counterReducer
-
- }
-
- });
根据具体的业务情况选择
...
Redux Toolkit (本质 安装@reduxjs/toolkit 包)- NPM
-
- npm install @reduxjs/toolkit
-
- Yarn
-
- yarn add @reduxjs/toolkit
React Redux 应用redux + ts 为例npx create-react-app my-app --template redux-typescript
store --- configureStore()
slice 并导出
- import { createSlice } from '@reduxjs/toolkit';
-
- export interface CounterState {
-
- value: number;
-
- title: string
-
- }
-
- const initialState: CounterState = {
-
- value: 0,
-
- title: "this is redux toolkit"
-
- };
-
- // 创建一个 Slice
-
- export const counterSlice = createSlice({
-
- name: 'counter',
-
- initialState,
-
- // 定义 reducers 并生成关联的操作
-
- reducers: {
-
- // 定义一个加的方法
-
- increment: (state) => {
-
- state.value += 1;
-
- },
-
- // 定义一个减的方法
-
- decrement: (state) => {
-
- state.value -= 1;
-
- },
-
- },
-
- });
-
- // 导出加减的方法
-
- export const { increment, decrement } = counterSlice.actions;
-
- // 默认导出
-
- export default counterSlice.reducer;
configureStore() 的 reducer 对象上
store 在入口文件中加载到全局即可,这样一个简单的状态管理就完成了。通过 provide 的方式将 store 挂载到全局
- import { createRoot } from 'react-dom/client';
-
- import { Provider } from 'react-redux';
-
- import { store } from './app/store';
-
- const container = document.getElementById('root')!;
-
- const root = createRoot(container);
-
- root.render(
-
-
-
-
-
-
-
-
-
-
-
- );
useAppSelector hooks 查看 store的数据
- import { useAppSelector } from '../../app/hooks';
-
- import { selectCount } from './counterSlice';
-
- export function Counter() {
-
- const count = useAppSelector(selectCount);
-
- return (
-
- {count}
-
- );
-
- }
useAppDispatch hooks 改变 store的状态
- import { useAppDispatch } from '../../app/hooks';
-
- import {
-
- decrement,
-
- increment,
-
- } from './counterSlice';
-
- export function Counter() {
-
- const dispatch = useAppDispatch();
-
- return (
-
-
-
-
-
-
-
- className={styles.button}
-
- aria-label="Decrement value"
-
- onClick={() => dispatch(decrement())}
-
- >
-
- -(减少)
-
-
-
- {count}
-
-
-
- className={styles.button}
-
- aria-label="Increment value"
-
- onClick={() => dispatch(increment())}
-
- >
-
- +(增加)
-
-
-
-
-
-
-
- );
-
- }
创建异步的 action --- createAsyncThunk() (extraReducers 可选)
createAsyncThunk
是 Redux Toolkit 提供的一个函数,用于简化处理异步操作的创建。它允许我们定义一个异步的 thunk action,该 action 可以处理异步逻辑并在请求开始、成功或失败时分发相应的 action。
方法触发的时候会有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)
与传统异步处理的对比: 对比传统的 Redux 异步处理方式,如手动编写多个 action 和 reducer 来处理异步操作, createAsyncThunk 能够大大简化异步操作的处理流程,减少了重复的代码。
extraReducers
可以让 slice 处理在别处定义的 actions,包括由 createAsyncThunk 或其他 slice 生成的 actions 。
- // 创建方法 createAsyncThunk
-
- export const incrementAsync = createAsyncThunk(
-
- 'counter/fetchCount',
-
- async (amount: number) => {
-
- const response = await fetchCount(amount);
-
- return response.data;
-
- }
-
- );
-
- export const counterSlice = createSlice({
-
- name: 'counter',
-
- initialState,
-
- extraReducers: (builder) => {
-
- builder
-
- .addCase(incrementAsync.pending, (state) => {
-
- state.status = 'loading';
-
- })
-
- .addCase(incrementAsync.fulfilled, (state, action) => {
-
- state.status = 'idle';
-
- state.value += action.payload;
-
- })
-
- .addCase(incrementAsync.rejected, (state) => {
-
- state.status = 'failed';
-
- });
-
- },
-
- });
基于此,一个简易版的 Redux Tookit 应用就完成了,我们可以通过 chrome 提供的Redux DevTools 工具来查看效果
总结
基于此 Redux Toolkit 的核心功能和优势有了更深入的理解。Redux Toolkit 作为一个简化 Redux 开发流程的利器,可以帮助开发者更加高效地管理应用的状态,减少重复代码,提高开发效率。
该文章在创建 RTK 时,直接用官网的命令 react + ts 生成了,如果现在已有react/vue...等其他的项目,我们只需安装@reduxjs/toolkit包即可,无需在重启项目。
参考文章:
https://stackoverflow.com/questions/52074622/store-getstate-or-mapstatetoprops-in-component
redux中文官网 https://cn.redux.js.org/introduction/getting-started
redux tookit 中文官方文档 https://cn.redux-toolkit.js.org/
- END -
关于奇舞团
奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。
