0902Redux_状态管理-react-仿低代码平台项目

文章目录

    • 1 Redux 概述
      • 1.1 核心概念
      • 1.2 基本组成
      • 1.3 工作流程
      • 1.4 中间件(Middleware)
      • 1.5 适用场景
      • 1.6 优缺点
      • 1.7 Redux Toolkit(现代推荐)
      • 1.8 与其他工具的对比
      • 1.9 总结
    • 2 todoList 待办事项案例
    • 3 Redux开发者工具
      • 3.1 核心功能
      • 3.2 安装与配置
        • 步骤 1:安装浏览器扩展
        • 步骤 2:配置 Redux Store
      • 3.3 使用示例
        • 1. 打开 DevTools
        • 2. 查看状态树
        • 3. 追踪 Action 历史
        • 4. 时间旅行调试
        • 5. 导出/导入状态
      • 3.4 高级功能
      • 3.5 常见问题
        • Q1: DevTools 不显示数据?
        • Q2: 生产环境如何禁用 DevTools?
        • Q3: 支持其他状态库吗?
      • 3.6 总结
    • 结语

1 Redux 概述

Redux 是一个用于 JavaScript 应用的可预测状态管理库,主要用于管理应用中的全局状态。它通过集中化的状态存储和严格的更新规则,使状态变化更加可控和可追踪。以下是 Redux 的核心概念、工作原理及特点:


1.1 核心概念

  1. 单一数据源(Single Source of Truth)
    所有状态存储在一个 Store 对象中,形成状态树(State Tree)。这简化了状态的读写和调试。
  2. 状态只读(State is Read-Only)
    唯一修改状态的方式是触发 Action(一个描述“发生了什么”的普通对象)。确保状态不会被随意修改。
  3. 纯函数修改(Changes with Pure Functions)
    通过 Reducer 函数处理 Action,返回新状态。Reducer 是纯函数(输入确定,输出确定,无副作用)。

1.2 基本组成

  1. Store

    • 保存全局状态的容器。
    • 通过 createStore(reducer) 创建(现代推荐使用 @reduxjs/toolkitconfigureStore)。
    • 提供 getState() 获取状态、dispatch(action) 触发更新、subscribe(listener) 监听变化。
  2. Action

    • 一个包含 type 字段的普通对象,描述发生了什么事。
    • 可携带额外数据(如 payload)。
    const incrementAction = { type: 'INCREMENT', payload: 1 };
    
  3. Reducer

    • 接收当前状态和 Action,返回新状态。
    • 必须是无副作用的纯函数。
    function counterReducer(state = 0, action) {switch (action.type) {case 'INCREMENT':return state + action.payload;default:return state;}
    }
    

1.3 工作流程

  1. 用户触发操作(如点击按钮)。
  2. 应用 派发(Dispatch)一个 Action(例如 { type: 'INCREMENT' })。
  3. Redux 调用 Reducer,根据 Action 类型计算新状态。
  4. Store 更新,所有订阅了状态变化的组件重新渲染。

redux数据流如下图所示:

在这里插入图片描述


1.4 中间件(Middleware)

  • 用于扩展 Redux 功能,处理异步操作或副作用(如 API 请求)。

  • 常用中间件:redux-thunk(处理异步)、redux-saga(复杂异步流)、redux-logger(日志记录)。

  • 示例(使用 redux-thunk 发起异步请求):

    const fetchData = () => {return (dispatch) => {dispatch({ type: 'FETCH_START' });fetch('/api/data').then(res => res.json()).then(data => dispatch({ type: 'FETCH_SUCCESS', payload: data })).catch(error => dispatch({ type: 'FETCH_ERROR', error }));};
    };
    

1.5 适用场景

  • 复杂的大型应用,多个组件依赖同一状态。
  • 需要跟踪状态变化历史(如时间旅行调试)。
  • 跨组件、页面或路由的状态共享。

1.6 优缺点

优点

  • 状态集中管理,易于调试(结合 Redux DevTools)。
  • 严格的更新模式确保可预测性。
  • 丰富的中间件生态。

缺点

  • 模板代码较多(可通过 Redux Toolkit 简化)。
  • 学习曲线较陡,尤其是异步处理。
  • 可能对小型项目过于复杂。

1.7 Redux Toolkit(现代推荐)

Redux 官方提供的工具集,简化 Redux 代码:

  • createSlice:自动生成 Action 和 Reducer。
  • configureStore:集成中间件和 DevTools。
  • createAsyncThunk:简化异步操作。
    示例:
import { createSlice } from '@reduxjs/toolkit';const counterSlice = createSlice({name: 'counter',initialState: 0,reducers: {increment: (state) => state + 1,decrement: (state) => state - 1,},
});export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

1.8 与其他工具的对比

  • Context API:适合简单场景,但缺乏 Redux 的中间件、调试工具和性能优化。
  • MobX:基于响应式编程,更适合追求简洁的小型项目。
  • Zustand:轻量级,API 更简单,适合中等复杂度应用。

1.9 总结

Redux 通过严格的单向数据流和集中化状态管理,解决了复杂应用的状态混乱问题。尽管需要编写一定模板代码,但结合 Redux Toolkit 和中间件,它仍是大型 React 应用状态管理的可靠选择。对于简单场景,可优先考虑轻量方案(如 Context API 或 Zustand)。

2 todoList 待办事项案例

状态todoList.tx代码如下:

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { nanoid } from "nanoid";export type TodoItemType = {id: string;title: string;completed: boolean;
};const INIT_STATE: TodoItemType[] = [{ id: nanoid(5), title: "吃饭", completed: false },{ id: nanoid(5), title: "睡觉", completed: false },
];export const todoListSlice = createSlice({name: "todoList",initialState: INIT_STATE,reducers: {addTodo(state: TodoItemType[], action: PayloadAction<TodoItemType>) {return [...state, action.payload];},removeTodo(state: TodoItemType[], action: PayloadAction<string>) {return state.filter((todo) => todo.id !== action.payload);},toggleCompleted(state: TodoItemType[], action: PayloadAction<string>) {return state.map((todo) => {const { id, completed } = todo;if (id !== action.payload) {return todo;}return {...todo,completed: !completed,};});},},
});export const { addTodo, removeTodo, toggleCompleted } = todoListSlice.actions;export default todoListSlice.reducer;

store/index.ts扩展todoList模块代码如下:

import { configureStore } from "@reduxjs/toolkit";
import countReducer from "./count";
import todoListReducer, { TodoItemType } from './todoList'export type StateType = {count: number,todoList: TodoItemType
}export default configureStore({reducer: {count: countReducer,todoList: todoListReducer// 扩展其他模块},
});

代办页面TodoList.tsx代码如下所示:

import { FC } from "react";
import { useSelector, useDispatch } from "react-redux";
import {addTodo,removeTodo,TodoItemType,toggleCompleted,
} from "../store/todoList";
import { StateType } from "../store";
import { nanoid } from "nanoid";const TodoList: FC = () => {const todoList = useSelector<StateType>((state) => state.todoList) as TodoItemType[];const dispatch = useDispatch();function add() {const id = nanoid(5);dispatch(addTodo({id,title: `待办事项-${id}`,completed: false,}));}function del(id: string) {dispatch(removeTodo(id));}function toggle(id: string) {dispatch(toggleCompleted(id));}return (<><p>todoList demo</p><div><button onClick={() => add()}>添加 todo</button></div><ul>{todoList.map((todo) => {const { id, title, completed } = todo;return (<likey={id}style={{ textDecoration: completed ? "line-through" : "" }}><span onClick={() => toggle(id)}>{title}</span>&emsp;<button onClick={() => del(id)}>删除</button></li>);})}</ul></>);
};export default TodoList;

效果如下图所示:在这里插入图片描述

3 Redux开发者工具

Redux DevTools 是一个强大的浏览器开发者工具扩展,用于调试 Redux 应用的状态变化。它提供了时间旅行调试、状态快照查看、Action 追踪等功能,极大简化了复杂状态管理的调试过程。以下是 Redux DevTools 的核心功能和使用指南:


3.1 核心功能

  1. 实时状态监控
    • 可视化查看整个 Redux Store 的状态树。
    • 支持展开/折叠嵌套对象,快速定位状态字段。
  2. Action 历史追踪
    • 记录所有派发的 Action 及其触发顺序。
    • 显示每个 Action 的 typepayload 信息。
  3. 时间旅行调试(Time Travel)
    • 通过回放 Action 历史,动态切换应用状态到任意时间点。
    • 直接跳过或撤销某个 Action,验证状态变化的正确性。
  4. 状态差异对比
    • 高亮显示两次状态变更之间的差异(Diff 功能)。
  5. 导入/导出状态
    • 将当前状态导出为 JSON 文件,方便共享或复现问题。
    • 导入外部状态文件,快速还原调试场景。
  6. 远程调试
    • 支持跨设备调试(如手机端与电脑端同步状态)。

3.2 安装与配置

步骤 1:安装浏览器扩展
  • Chrome: Redux DevTools Chrome 扩展
  • Firefox: Redux DevTools Firefox 扩展
步骤 2:配置 Redux Store
  • Redux Toolkit(推荐)**:
    configureStore 已默认启用 DevTools,无需额外配置。

    import { configureStore } from '@reduxjs/toolkit';const store = configureStore({reducer: rootReducer,middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
    });
    

3.3 使用示例

1. 打开 DevTools
  • 浏览器开发者工具 → 切换到 Redux 标签页。
    在这里插入图片描述
2. 查看状态树
  • State 面板中浏览当前 Store 的完整状态。
3. 追踪 Action 历史
  • Actions 面板中查看所有已派发的 Action,点击任意 Action 查看其详情和对应状态快照。
4. 时间旅行调试
  • 点击 Action 列表中的某个条目,应用状态会自动回退到该时间点。
  • 使用 跳过(Skip)撤销(Revert) 按钮手动控制状态变更。
5. 导出/导入状态
  • 点击 Export 导出当前状态为 JSON 文件。
  • 点击 Import 导入外部状态文件,快速恢复调试场景。

3.4 高级功能

  1. Action 日志过滤

    • 通过关键字或正则表达式过滤特定 Action(如 FETCH_*)。
  2. 锁定状态变更

    • 在调试时锁定状态,防止意外修改。
  3. 远程调试配置

    • 使用 remote-redux-devtools 包调试远程设备或服务端渲染的应用:

      javascript

      复制

      下载

      import { composeWithDevTools } from '@redux-devtools/extension';
      const store = createStore(reducer,composeWithDevTools({ hostname: 'localhost', port: 8000 })
      );
      

3.5 常见问题

Q1: DevTools 不显示数据?
  • 确保正确配置了 Redux Store(如使用 composeWithDevTools)。
  • 检查是否安装了浏览器扩展并启用了 Redux 标签页。
  • 确认应用实际使用了 Redux(如非 React 应用需手动连接)。
Q2: 生产环境如何禁用 DevTools?
  • 通过环境变量动态关闭:

    javascript

    复制

    下载

    const composeEnhancers = process.env.NODE_ENV === 'development'? composeWithDevTools({ trace: true }): compose;const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));
    
Q3: 支持其他状态库吗?
  • 支持部分兼容 Redux API 的库(如 Zustand、Flux),但功能可能受限。

3.6 总结

Redux DevTools 是 Redux 开发者的必备工具,通过时间旅行调试和状态可视化大幅提升开发效率。结合 Redux Toolkit 的默认集成,可以快速上手并应用于复杂应用的调试场景。

结语

❓QQ:806797785

⭐️仓库地址:https://gitee.com/gaogzhen

⭐️仓库地址:https://github.com/gaogzhen

[1]Redux官网[CP/OL].

[2]Redux Toolkit官网[CP/OL].

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/79321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《ATPL地面培训教材13:飞行原理》——第6章:阻力

翻译&#xff1a;Leweslyh&#xff1b;工具&#xff1a;Cursor & Claude 3.7&#xff1b;过程稿 第6章&#xff1a;阻力 目录 引言寄生阻力诱导阻力减少诱导阻力的方法升力对寄生阻力的影响飞机总阻力飞机总重量对总阻力的影响高度对总阻力的影响构型对总阻力的影响速度稳…

C++总结01-类型相关

一、数据存储 1.程序数据段 • 静态&#xff08;全局&#xff09;数据区&#xff1a;全局变量、静态变量 • 堆内存&#xff1a;程序员手动分配、手动释放 • 栈内存&#xff1a;编译器自动分配、自动释放 • 常量区&#xff1a;编译时大小、值确定不可修改 2.程序代码段 •…

【Hot 100】94. 二叉树的中序遍历

目录 引言二叉树的中序遍历我的解题代码优化更清晰的表述建议&#xff1a; &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;【Hot 100】94. 二叉树的中序遍历❣️ 寄语&#xff1a;书到用时方恨少&#xff…

大语言模型(LLMs)微调技术总结

文章目录 全面总结当前大语言模型&#xff08;LLM&#xff09;微调技术1. 引言2. 为什么需要微调&#xff1f;3. 微调技术分类概览4. 各种微调技术详细介绍4.1 基础微调方法4.1.1 有监督微调&#xff08;Supervised Fine-Tuning, SFT&#xff09;4.1.2 全参数微调&#xff08;F…

解决Maven项目中报错“java不支持版本6即更高的版本 7”

错误背景 当Maven项目编译或运行时出现错误提示 Java不支持版本6即更高的版本7&#xff0c;通常是由于项目配置的JDK版本与当前环境或编译器设置不一致导致的。例如&#xff1a; 项目配置的Java版本为6或7&#xff0c;但实际使用的是JDK 17。Maven或IDE的编译器未正确指定目标…

C++笔记-多态(包含虚函数,纯虚函数和虚函数表等)

1.多态的概念 多态(polymorphism)的概念:通俗来说&#xff0c;就是多种形态。多态分为编译时多态(静态多态)和运行时多态(动态多态)&#xff0c;这里我们重点讲运行时多态&#xff0c;编译时多态(静态多态)和运行时多态(动态多态)。编译时多态(静态多态)主要就是我们前面讲的函…

【Unity】MVP框架的使用例子

在提到MVP之前&#xff0c;可以先看看这篇MVC的帖子&#xff1a; 【Unity】MVC的简单分享以及一个在UI中使用的例子 MVC的不足之处&#xff1a; 在MVC的使用中&#xff0c;会发现View层直接调用了Model层的引用&#xff0c;即这两个层之间存在着一定的耦合性&#xff0c;而MV…

前端js学算法-实践

1、两数之和 const twoSum (nums, target) > {const obj {}for (let m 0; m < nums.length; m) {const cur nums[m]const diff target - curif(obj.hasOwnProperty(diff)){ // 查询对象中是否存在目标值-当前值键值对console.log([obj[diff], m]) // 存在则直接获取…

《MATLAB实战训练营:从入门到工业级应用》趣味入门篇-用声音合成玩音乐:MATLAB电子琴制作(超级趣味实践版)

《MATLAB实战训练营&#xff1a;从入门到工业级应用》趣味入门篇-用声音合成玩音乐&#xff1a;MATLAB电子琴制作&#xff08;超级趣味实践版&#xff09; 开篇&#xff1a;当MATLAB遇见音乐 - 一场数字与艺术的浪漫邂逅 想象一下&#xff0c;你正坐在一台古老的钢琴前&#x…

实战探讨:为什么 Redis Zset 选择跳表?

在了解了跳表的原理和实现后&#xff0c;一个常见的问题&#xff08;尤其是在面试中&#xff09;随之而来&#xff1a;为什么像 Redis 的有序集合 (Zset) 这样的高性能组件会选择使用跳表&#xff0c;而不是大家熟知的平衡树&#xff08;如红黑树&#xff09;呢&#xff1f; 对…

数据结构-线性结构(链表、栈、队列)实现

公共头文件common.h #define TRUE 1 #define FALSE 0// 定义节点数据类型 #define DATA_TYPE int单链表C语言实现 SingleList.h #pragma once#include "common.h"typedef struct Node {DATA_TYPE data;struct Node *next; } Node;Node *initList();void headInser…

高中数学联赛模拟试题精选学数学系列第3套几何题

△ A B C \triangle ABC △ABC 的内切圆 ⊙ I \odot I ⊙I 分别与边 B C BC BC, C A CA CA, A B AB AB 相切于点 D D D, E E E, F F F, D D ′ DD DD′ 为 ⊙ I \odot I ⊙I 的直径, 过圆心 I I I 作直线 A D ′ AD AD′ 的垂线 l l l, 直线 l l l 分别与 D E DE…

使用 ossutil 上传文件到阿里云 OSS

在处理文件存储和传输时&#xff0c;阿里云的对象存储服务&#xff08;OSS&#xff09;是一个非常方便的选择。特别是在需要批量上传文件或通过命令行工具进行文件管理时&#xff0c;ossutil提供了强大的功能。本文将详细说明如何使用 ossutil 上传文件到阿里云 OSS&#xff0c…

DeepSeek与MySQL:开启数据智能新时代

目录 一、引言&#xff1a;技术融合的力量二、DeepSeek 与 MySQL&#xff1a;技术基石2.1 DeepSeek 技术探秘2.2 MySQL 数据库深度解析 三、DeepSeek 与 MySQL 集成&#xff1a;从理论到实践3.1 集成原理剖析3.2 集成步骤详解 四、应用案例&#xff1a;实战中的价值体现4.1 电商…

WebAPI项目从Newtonsoft.Json迁移到System.Text.Json踩坑备忘

1.控制器层方法返回类型不能为元组 控制器层方法返回类型为元组时&#xff0c;序列化结果为空。 因为元组没有属性只有field&#xff0c;除非使用IncludeFields参数专门指定&#xff0c;否则使用System.Text.Json进行序列化时不会序列化field var options new JsonSerializ…

202553-sql

目录 一、196. 删除重复的电子邮箱 - 力扣&#xff08;LeetCode&#xff09; 二、602. 好友申请 II &#xff1a;谁有最多的好友 - 力扣&#xff08;LeetCode&#xff09; 三、176. 第二高的薪水 - 力扣&#xff08;LeetCode&#xff09; 一、196. 删除重复的电子邮箱 - 力扣…

Spring Boot的GraalVM支持:构建低资源消耗微服务

文章目录 引言一、GraalVM原生镜像技术概述二、Spring Boot 3.x的GraalVM支持三、适配GraalVM的关键技术点四、构建原生镜像微服务实例五、性能优化与最佳实践总结 引言 微服务架构已成为企业应用开发的主流模式&#xff0c;但随着微服务数量的增加&#xff0c;资源消耗问题日…

pip 常用命令及配置

一、python -m pip install 和 pip install 的区别 在讲解 pip 的命令之前&#xff0c;我们有必要了解一下 python -m pip install 和 pip install 的区别&#xff0c;以便于我们在不同的场景使用不同的方式。 python -m pip install 命令使用 python 可执行文件将 pip 模块作…

Vue高级特性实战:自定义指令、插槽与路由全解析

一、自定义指令 1.如何自定义指令 ⑴.全局注册语法 通过 Vue.directive 方法注册&#xff0c;语法格式为&#xff1a; Vue.directive(指令名, {// 钩子函数&#xff0c;元素插入父节点时触发&#xff08;仅保证父节点存在&#xff0c;不一定已插入文档&#xff09;inserted(…

本地大模型编程实战(32)用websocket显示大模型的流式输出

在与 LLM(大语言模型) 对话时&#xff0c;如果每次都等 LLM 处理完毕再返回给客户端&#xff0c;会显得比较卡顿&#xff0c;不友好。如何能够像主流的AI平台那样&#xff1a;可以一点一点吐出字符呢&#xff1f; 本文将模仿后端流式输出文字&#xff0c;前端一块一块的显示文字…