当前位置: 首页 > news >正文

redux toolkit (RTK)

简介

Redux Toolkit(简称 RTK)是 Redux 官方推出的工具集,旨在解决传统 Redux 开发中的一些痛点问题。

相比直接使用 react-redux ,它使用更为简便,主要解决了以下诸多核心问题:

1. 简化样板代码;

2. 简化不可变状态的更新;

3. 简化 Store 配置;

4. 简化异步逻辑处理。

详解

1. 简化样板代码

传统 Redux 开发需要手动编写:

  • Action Type 常量(如 const ADD_TODO = 'ADD_TODO'
// actionTypes.js
export const ADD_TODO = 'todos/ADD_TODO'; // 新增待办
export const TOGGLE_TODO = 'todos/TOGGLE_TODO'; // 切换待办状态
export const DELETE_TODO = 'todos/DELETE_TODO'; // 删除待办
  • Action Creator 函数(如 const addTodo = (text) => ({ type: ADD_TODO, payload: text })
// actions.js
import { ADD_TODO, TOGGLE_TODO, DELETE_TODO } from './actionTypes';// 新增待办的 Action Creator(需手动传递 text 参数,绑定 type)
export const addTodo = (text) => {return {type: ADD_TODO, // 手动关联第一步定义的常量payload: text, // 携带数据(需手动命名 payload,无统一约定)};
};// 切换待办状态的 Action Creator(需手动传递 id 参数)
export const toggleTodo = (id) => {return {type: TOGGLE_TODO,payload: id,};
};// 删除待办的 Action Creator(需手动传递 id 参数)
export const deleteTodo = (id) => {return {type: DELETE_TODO,payload: id,};
};
  • Reducer 中的 switch-case 逻辑(处理不同 Action Type)
// reducer.js
import { ADD_TODO, TOGGLE_TODO, DELETE_TODO } from './actionTypes';// 初始状态(需手动定义)
const initialState = [];// Reducer 函数(手动编写 switch-case 匹配每个 Action Type)
const todoReducer = (state = initialState, action) => {switch (action.type) {// 处理“新增待办”:手动实现不可变更新(...state 复制旧状态)case ADD_TODO:return [...state, // 复制原有待办列表{id: Date.now(), // 手动生成 idtext: action.payload, // 从 Action 中取数据done: false, // 默认未完成},];// 处理“切换待办状态”:手动遍历数组,返回新对象case TOGGLE_TODO:return state.map((todo) =>todo.id === action.payload ? { ...todo, done: !todo.done } // 复制单个 todo 并修改状态: todo // 未匹配的 todo 保持不变);// 处理“删除待办”:手动过滤数组,返回新数组case DELETE_TODO:return state.filter((todo) => todo.id !== action.payload);// 默认返回原状态(必须写,否则初始状态会错)default:return state;}
};export default todoReducer;

RTK 解决方案
通过 createSlice 自动生成 Action Type、Action Creator 和 Reducer,大幅减少代码量。

// Redux Toolkit 写法
import { createSlice } from '@reduxjs/toolkit';const todoSlice = createSlice({name: 'todos',initialState: [],reducers: {addTodo: (state, action) => {// 直接修改状态(内部通过 Immer 实现不可变更新)state.push({ id: Date.now(), text: action.payload, done: false });},toggleTodo: (state, action) => {const todo = state.find(t => t.id === action.payload);if (todo) todo.done = !todo.done;}}
});// 自动生成 Action Creator
export const { addTodo, toggleTodo } = todoSlice.actions;
// 自动生成 Reducer
export default todoSlice.reducer;

2. 简化不可变状态更新

传统 Redux 写法:

通过不可变方式更新状态(如 return { ...state, ...newState }),手动编写容易出错且繁琐。

RTK 解决方案
内置 Immer 库,允许在 Reducer 中直接 “修改” 状态(如 state.push(...)),Immer 会自动将其转换为不可变更新,既直观又不易出错。

3. 简化 Store 配置

传统 Redux 需要手动配置:

  • createStore
  • 中间件(如 applyMiddleware(thunk)
  • 开发者工具(window.__REDUX_DEVTOOLS_EXTENSION__
// store.js
import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk'; // 需手动安装(npm install redux-thunk)
import todoReducer from './reducer';// 若有多个 Reducer,需手动合并(combineReducers)
const rootReducer = combineReducers({todos: todoReducer, // 命名状态键(todos 对应 todoReducer 的状态)
});// 手动配置中间件和 DevTools(这段代码几乎每个项目都重复)
const store = createStore(rootReducer,// 开启 Redux DevTools(需手动写条件判断,兼容生产环境)window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),applyMiddleware(thunk) // 手动集成 Thunk 中间件
);export default store;

RTK 解决方案
configureStore 函数一站式配置 Store,默认集成 Redux Thunk、Redux DevTools,并简化中间件设置:

// Redux Toolkit 写法
import { configureStore } from '@reduxjs/toolkit';
import todoReducer from './todoSlice';export const store = configureStore({reducer: {todos: todoReducer}
});

4. 简化异步逻辑处理

传统 Redux 处理异步(如 API 请求):

  • 手动编写异步 Action(依赖 redux-thunk
  • 定义加载中、成功、失败等 Action Type
  • 在 Reducer 中处理多种状态(isLoadingerror 等)

RTK 解决方案
createAsyncThunk 自动生成异步 Action,结合 createSlice 的 extraReducers 处理异步状态:

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { fetchTodos } from './api';// 自动生成 pending/fulfilled/rejected 三种 Action
export const getTodos = createAsyncThunk('todos/fetchTodos',async () => {const response = await fetchTodos();return response.data;}
);const todoSlice = createSlice({name: 'todos',initialState: { items: [], isLoading: false, error: null },reducers: {},extraReducers: (builder) => {builder.addCase(getTodos.pending, (state) => {state.isLoading = true;}).addCase(getTodos.fulfilled, (state, action) => {state.isLoading = false;state.items = action.payload;}).addCase(getTodos.rejected, (state, action) => {state.isLoading = false;state.error = action.error.message;});}
});

总结

Redux Toolkit 并非替代 Redux 或 React-Redux,而是在它们的基础上封装了一套最佳实践,解决了传统开发中的样板代码冗余、不可变更新繁琐、配置复杂、异步逻辑处理麻烦等问题,让 Redux 开发更高效、更易维护。

代码示例

[代码]:

index.js:

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './slices/counterSlice'
import userReducer from './slices/userSlice'export const store = configureStore({reducer: {counter: counterReducer,user: userReducer},
});

slices/userSlice.js:

import { createSlice } from '@reduxjs/toolkit'const userSlice = createSlice({name: 'user',initialState: {name: '张三',age: 18,},reducers: {setName(state, action) {state.name = action.payload},setAge(state, action) {state.age = action.payload},},
})
export const { setName, setAge } = userSlice.actions
export default userSlice.reducer

slices/counterSlice.js:

import { createSlice } from '@reduxjs/toolkit';const initialState = {counter: 0,
};const counterSlice = createSlice({name: 'counter',initialState,reducers: {increment: (state) => {state.counter += 1;},decrement: (state) => {state.counter -= 1;},incrementByAmount: (state, action) => {state.counter += action.payload;},},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

 组件中具体调用:

import React, { useEffect, useLayoutEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'// 1. react-redux
const ReactRedux = () => { let { age } = useSelector((state: any) => state.user)const dispatch = useDispatch()const changeUserAgeInStore = () => {// 改变状态管理器中的 user.agedispatch({type: 'user/setAge',payload: ++age})}return (<button onClick={ changeUserAgeInStore }>改变状态管理器中的 user.age</button>)
}

http://www.dtcms.com/a/356885.html

相关文章:

  • 蓝牙配对鉴权过程深度剖析:Just Works/Numeric Comparison/Passkey Entry/OOB 协议流程
  • KNN算法详解:从原理到实战(鸢尾花分类 手写数字识别)
  • node.js 安装步骤
  • Python教学:6. 循环
  • 巨头围猎“单人经济”:自助小火锅如何成为餐饮新破局点?
  • 淘宝扭蛋机小程序系统开发:打造个性化线上购物乐园
  • Anaconda、OpenCV安装配置方法
  • 老地方 新世界 |GitCodeAI 社区升级发布会来了
  • 【LeetCode每日一题】141. 环形链表 142.环形链表 II
  • 麒麟系统使用-VSCode运行.net过程中一些可能问题及解决办法
  • 【前端教程】JavaScript 对象与数组操作实战:从基础到优化
  • 课程视频怎么加密?在线教育机构常用的6个课程加密方法
  • 视频转音频
  • 学习Java30天(tcp的多开客户端和bs架构以及java高级)
  • R 语言 + 卒中 Meta 分析
  • 如何用 Kotlin 在 Android 手机开发一个小闹钟、计时器、秒表
  • Vue3+Ant-design-vue 实现树形穿梭框
  • Java中对泛型的理解
  • mes表结构思维导图
  • 基于机器学习的多个模型的预测Backtrader自动化交易系统设计
  • Java设计模式是什么?核心设计原则有哪些?
  • 编程速递:RAD Studio 13 即将到来的功能
  • Linux应用软件编程--->数据库
  • C++函数继承
  • 【C++闯关笔记】STL:vector的学习与使用
  • 论文阅读:ICLR 2024 GAIA: A Benchmark for General AI Assistants
  • DBeaver中禁用PostgreSQL SSL的配置指南
  • SQL Server 查看备份计划
  • Creed —— 设置玩家属性(生命/耐力/经验值等)
  • 初学python的我开始Leetcode题-17