【React】redux状态管理、react-redux状态管理高级封装模块化
【React】react组件传参、redux状态管理
- 一、redux全局状态管理
- 1、redux概述
- 2、redux的组成
- 1.1 State-状态
- 1.2 Action-事件
- 1.3 Reducer
- 1.4 Store
- 3、redux入门案例
- 1.1 前期准备
- 1.2 构建store
- 1.2.1 在src下新建store文件夹
- 1.2.2 在store文件夹下新建index.ts文件
- 1.2.3 在index.ts文件里编写redux核心代码
- 1.2.4 在store文件夹下新建reducer.ts文件
- 1.2.5 在index.ts文件中引入reducer.ts
- 1.2.6 到根目录下的入口文件index.ts文件导入store仓储对象
- 1.3 在组件中使用store
- 二、react-redux状态管理高级封装模块化
- 1、在store文件夹下新建NumStatus文件夹(管理num的模块)
- 2、在NumStatus文件夹下新建index.ts和reducer.ts文件
- 3、如果还有其他的状态需要管理,如新建ArrStatus文件夹(管理数组模块)
- 4、在index.ts文件中引入reducer.ts
- 5、在组件中使用store
- 6、模块化结束
一、redux全局状态管理
1、redux概述
- redux是一个JavaScript容器,用于进行全局的状态管理;
- redux三大核心;
-
单一数据源头:所有state都会被挂载到一个叫Object tree中,Object tree又只存在唯一的Store(理解为容器,存储Object tree,Object tree挂在state)中;
-
State是只读的:唯一改变state的方法就是触发
action
,触发action,store.dispatch ( {type: '字符串' , val: 1}),val自定义
-
使用纯函数来执行修改:编写
reducers
,接受state和action,并返回一个新的state;
-
2、redux的组成
1.1 State-状态
- 就是我们传递的数据,后端返回的数据、决定ui展示的状态等等;
1.2 Action-事件
- Action是把数据从应用传到store的载体(对象),它是store数据的唯一来源,一般来说,我们可以通过store.dispatch()将action传递给store;
- Action的特点
- Action的本质就是一个javaScript的普通对象;
- Action对象内部必须要有一个type属性来表示要执行的动作多数情况下,这个type会被定义成字符串常量;
- 除了type字段之外,action的结构随意进行定义;
- 而我们在项目中,更多的喜欢用action创建函数(就是创建action的地方);
- 只是描述了有事情要发生,并没有描述如何去更新state;
// Action创建函数
function addAction(params){//返回一个Action对象return {type:'add',//add为自定义...params}
}
1.3 Reducer
- Reducer本质就是一个函数,它用来响应发送过来的actions,然后经过处理,把 state发送给Store的;
- 在Reducer函数中,需要return返回值,这样Store才能接收到数据;
- 函数会接收两个参数,第一个参数是初始化 state,第二个参数是action;
const initState={...}
function reducer(state=initState,action){return {...}
}
1.4 Store
//构建store
import { createstore } from "redux";
//构建store对象
const store = createstore(传递reducer) ;
- Store 就是把action 与reducer联系到一起的对象;
- 主要职责:
- 维持应用的state
- 提供getState()方法获取state
- 提供dispatch()方法发送action
- 通过subscribe()来注册监听
- 通过subscribe()返回值来注销监听
3、redux入门案例
1.1 前期准备
- 打开VSCode终端
- 新建项目,输入npx create-react-app + 项目名称(自定义,注意最好不要中文)
- 删除多余的配置文件,只留下(App.css,App.js,index.js)并清除三个文件下不必要的代码
- 进入新的项目文件夹
- 安装redux相关依赖
npm i react-redux
npm i redux
//异步解决方案redux-thunk
npm i redux-thunk
//持久化redux
npm i redux-persist
- npm run start启动项目
1.2 构建store
1.2.1 在src下新建store文件夹
1.2.2 在store文件夹下新建index.ts文件
1.2.3 在index.ts文件里编写redux核心代码
//创建一个仓储对象,需要reducer作为对象
//本来是这么写的
import { createStore} from 'redux'
//但是改版之后,需要写成下面这个样子
import { legacy_createStore} from 'redux'
1.2.4 在store文件夹下新建reducer.ts文件
//用来管理数据的
const initData={
num :20
}
// state是状态数据的原始值,action={type : "add " ,data:{}
function reducer(state=initData,action){//!!!!不能操作修改旧的数据//不能直接修改老的状态数据,应该根据老的状态数据,生成一个新的状态数据,然后返回const newState=JSON.parse(JSON.stringify(state))switch(action.type){case "add1":newState.num++break;case "add2":newState.num+=action.valbreak;break;default:break;}return newState;
}
export default reducer
1.2.5 在index.ts文件中引入reducer.ts
//创建一个仓储对象,需要reducer作为对象
import {legacy_createStore,applyMiddleware}from ' redux';
import reduxThunk from 'redux-thunk'
import { persistStore, persistReducer } from "redux-persist";//持久化
import storage from "redux-persist/lib/storage";
import reducer from './reducer ';
const persistConfig = {key: "xxx",storage: storage,// whitelist:['LoadingReducers'],//想持久化哪个
};
const persistReducers = persistReducer(persistConfig, reducer )
const store = legacy_createStore(persistReducers, applyMiddleware(reduxThunk))
let persisttore = persistStore(store)
export { store, persisttore }
1.2.6 到根目录下的入口文件index.ts文件导入store仓储对象
- 将store与项目挂钩,导入store仓储对象
//这里可能还引入其他东西,为了简洁,我就不写了
...
//状态管理
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
//持久化
import { PersistGate } from "redux-persist/lib/integration/react";
import {store,persisttore} from "@/store";
import App from "./App" ;
ReactDOM.render(
// 将仓储对象传递给根组件<Provider store={store}><PersistGate persistor={persisttore}><App /></PersistGate ></Provider>,
document.querySelector( "#root")
);
1.3 在组件中使用store
- 通过useselector获取仓库数据
import { useDispatch, useSelector } from "react-redux";
const View = () => {// 通过useSelector获取仓库数据const { num } = useSelector((state: { num: any }) => ({ num: state.num }));// 通过useDispatch修改仓库的数据const dispatch = useDispatch();const changeNum = () => {// dispatch ( {type: '字符串' , val: 1}),val自定义//同步的写法dispatch({ type: "add1" });//每点击一次加1dispatch({ type: "add2" ,val:10});//每点击一次加10// 异步的写法:dispatch ( 异步执行的函数)dispatch((dis:Function)=>{setTimeout(()=>{dis({ type: "add1" })},1000)})};return (<div className="home"><p>这是Page1页面内容</p><p>{num}</p><button onClick={changeNum}>按钮</button></div>);
};
export default View;
二、react-redux状态管理高级封装模块化
- 封装的目的:最终是有利于我们的开发或者维护
- 封装的思路:将来开发的时候只需要把数据和方法写入到这个状态文件中,例如:XxxxStatus/index.ts,而不需要再去操作其他的文件。
1、在store文件夹下新建NumStatus文件夹(管理num的模块)
2、在NumStatus文件夹下新建index.ts和reducer.ts文件
//index.ts
const store: any = {state: {isLoading: false},actions: {//只放同步的方法add1(newState:{num:number} ,action:{type : string}){newstate.num++,}add2(newstate:{num: number},action:{type: string,val:number}){newState.num+=action.val,},},asyncActions: {//react-redux的异步解决方案redux-thunk//只放异步的方法//优化redux-thunk的异步写法(模仿vuex的写法)asyncAdd1(dispatch: Function){setTimeout(()=>{dispatch({type: "add1"})},1000)},},// 名字统一管理actionNames: {}
}
//定义一个全局
let actionNames: any = {}
for (let key in store.actions) {actionNames[key] = key
}
store.actionNames = actionNames
export default store
//reducer.ts
//处理数据
import handle from "./index"
let reducer = (state = { ...handle.state }, action: { type: string}) => {let newState = JSON.parse(JSON.stringify(state))for (let key in handle.actionNames) {if (action.type === handle.actionNames[key]) {handle.actions[handle.actionNames[key]](newState, action)break;}}return newState
}
export default reducer
3、如果还有其他的状态需要管理,如新建ArrStatus文件夹(管理数组模块)
- 在ArrStatus文件夹下新建index.ts和reducer.ts文件
- index.ts内容如下
//处理数据
const store ={
state:{sarr:[10,20,30]
},
actions:{sarrpush(newState:{sarr:number[},action:{type:string, val:number})(newstate.sarr.push(action.val)}
}, asyncActions: {//只放异步的方法},// 名字统一管理actionNames: {}
}
//定义一个全局
let actionNames: any = {}
for (let key in store.actions) {actionNames[key] = key
}
store.actionNames = actionNames
export default store
- reducer.ts内容都是 一样的
总结,不同的模块只有state和action里的内容,其他都一样
4、在index.ts文件中引入reducer.ts
- 引入reducer.ts,
combineReducers
组合各个模块的reducer
//创建一个仓储对象,需要reducer作为对象
import {legacy_createStore,combineReducers,applyMiddleware}from ' redux';
import reduxThunk from 'redux-thunk'
import { persistStore, persistReducer } from "redux-persist";//持久化
import storage from "redux-persist/lib/storage";
import NumStatusrReducer from "./NumStatus/reducer"
import ArrstatusReducer from "./Arrstatus/reducer"
//组合各个模块的reducer
const reducers = combineReducers(iNumStatusReducer,ArrstatusReducer
})
const persistConfig = {key: "xxx",storage: storage,// whitelist:['LoadingReducers'],//想持久化哪个
};
const persistReducers = persistReducer(persistConfig, reducers)
const store = legacy_createStore(persistReducers, applyMiddleware(reduxThunk))
let persisttore = persistStore(store)
export { store, persisttore }
5、在组件中使用store
- 通过useselector获取仓库数据,跟1.3一样,唯一不一样的就是获取state不一样了
// 通过useSelector获取仓库数据const { num } = useSelector((state: { num: any }) => ({ num: state.NumStatusReducer.num }));
6、模块化结束
总结
- 不同的模块只有state和action里的内容,其他都一样;
- 相同模块下如果需要添加同步方法,则只需在index.ts文件添加方法,在对应的组件内部调用
dispatch("add3")
即可
actions: {add1(newState:{num:number} ,action:{type : string}){newstate.num++,}add2(newstate:{num: number},action:{type: string,val:number}){newState.num+=action.val,},add3(){....}},
- 相同模块下如果需要添加异步方法,则只需在index.ts文件添加方法,在对应的组件内部调用
dispatch(调用状态管理中的asyncAddx),即dispatch(state.NumStatusReducer.asyncAdd2)
asyncActions: {asyncAdd1(dispatch: Function){setTimeout(()=>{dispatch({type: "add1"})},1000)},asyncAdd2(){}},```
相关文章:

【React】redux状态管理、react-redux状态管理高级封装模块化
【React】react组件传参、redux状态管理 一、redux全局状态管理1、redux概述2、redux的组成1.1 State-状态1.2 Action-事件1.3 Reducer1.4 Store 3、redux入门案例1.1 前期准备1.2 构建store1.2.1 在src下新建store文件夹1.2.2 在store文件夹下新建index.ts文件1.2.3 在index.t…...
HAProxy 和负载均衡概念简介
简介 HAProxy,全称高可用代理,是一款流行的开源软件 TCP/HTTP 负载均衡器和代理解决方案,可在 Linux、macOS 和 FreeBSD 上运行。它最常见的用途是通过将工作负载分布到多台服务器(例如 Web、应用程序、数据库)上来提…...
【go】ent操作之CRUD与联表查询
文章目录 1 CRUD1.1 创建1.1.1 单条创建1.1.2 批量创建 1.2 查找1.2.1 查询单条 / 条件准确查询1.2.2 查询单条 / 条件模糊查询1.2.3 查询单条 / In1.2.4 查询全部 1.3 更新1.4 删除 2 联表查询2.1 O2M(一对多查询)2.1.1 增加Edge2.1.2 查询方法2.1.2.1 …...

服务器性能监控管理方法及工具
服务器是组织数据中心的主干,无论是优化的用户体验,还是管理良好的资源,服务器都能为您完成所有工作,保持服务器随时可用和可访问对于面向业务的应用程序和服务以最佳水平运行至关重要。 理想的服务器性能需要主动监控物理和虚拟…...
AUTOSAR汽车电子嵌入式编程精讲300篇-基于FPGA和CAN协议2.0B的总线控制器研究与设计
目录 前言 研究现状分析 2 CAN总线协议 2.1 CAN总线基本概念 2.2 物理层...
14.1 Ajax与JSON应用(❤❤)
14.1 Ajax与JSON应用 1. Ajax1.1 简介1.2 Ajax使用流程1. 前端创建XMLHttpRequest对象2. 发送Ajax请求3. 处理服务器响应4. 代码2. JSON2.1 简介2.2 JS解析JSON3. Ajax与JSON开发3.1 后端:用Jackson实现JSON序列化输出3.2 前端Ajax处理JSON3.3 Ajax工具...

ffmpeg命令生成器
FFmpeg 快速入门:命令行详解、工具、教程、电子书 – 码中人的博客FFmpeg 是一个强大的命令行工具,可以用来处理音频、视频、字幕等多媒体文件。本文介绍了 FFmpeg 的基本用法、一些常用的命令行参数,以及常用的可视化工具。https://blog.mzh…...
JavaScript基础速成
由于学web时只学了后端,现在到了前后端联调的场景发现看不懂前端代码,于是开始恶补 看了下基础内容发现html和css比较好看懂,但JavaScript比较迷,大概知道组件id绑定事件 下面选取看菜鸟教程补充的JS知识 JS的作用 JS是在html…...

openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志
文章目录 openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志215.1 性能日志概述215.2 性能日志收集的配置参数 openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志 215.1 性能日志概述 性能日志主要关注外部资源的访问性能问题。 性能日…...
在vs code的terminal,debug执行python main.py --train True
GPT4告诉我: 在VS Code中以debug状态执行带有参数(如--train)的main.py文件,你需要在launch.json配置文件中正确设置参数。以下是详细步骤: 打开你的main.py文件:确保你的main.py文件已经在VS Code中打开…...
docker 简单项目
要将服务器端口映射到容器端口,你可以使用 Docker 命令的 -p 选项。以下是基本的步骤: 1. **拉取镜像:** 在服务器上运行以下命令拉取你想要的 Docker 镜像,例如 Nginx: bash docker pull nginx 2. **运行容器…...

计算机毕业设计 基于SpringBoot的线上教育培训办公系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...

四、机器学习基础概念介绍
四、机器学习基础概念介绍 1_机器学习基础概念机器学习分类1.1 有监督学习1.2 无监督学习 2_有监督机器学习—常见评估方法数据集的划分2.1 留出法2.2 校验验证法(重点方法)简单交叉验证K折交叉验证(单独流出测试集)(常…...
Excel设置单元格下拉框(poi)
前言 年关在即,还在最后的迭代处理,还分了个其他同事的单,说是导出的Excel模版的2列要修改为下拉选项,过程很曲折,不说,以下其实就是一个笔记而已! 其实之前分享过阿里的EasyExcel设置单…...
api接口是什么意思,api接口该如何防护呢?
API接口:应用程序与服务之间的接口 什么是API接口 API是应用程序接口的缩写,指的是能够让不同的应用程序之间交换数据的一种方式。一个API接口就是应用程序与服务之间的接口,它定义了服务提供的功能和数据,以及应用程序如何访问这…...

PMP资料怎么学?PMP备考经验分享
PMP考试前大家大多都是提前备考个一两个月,但是有些朋友喜欢“不走寻常路”,并不打算去考PMP认证,想要单纯了解PMP,不管要不要考证,即使是仅仅学习了解一下我个人都非常支持,因为专业的基础的确能提高工作效…...
partition by list(msn_id)子句的含义
在数据库查询中,特别是在使用SQL语言时,"PARTITION BY" 子句用于对结果集进行分区,以便可以对每个分区进行单独的聚合操作。这是在执行窗口函数(如 ROW_NUMBER(), RANK(), SUM(), AVG() 等)时特别有用的。 …...

【C++】I/O多路转接详解(二)
在上一篇文章【C】I/O多路转接详解(一) 在出现EPOLL之后,随之而来的是两种事件处理模式的应运而生:Reator 和 Proactor,同步IO模型常用于Reactor模式,异步IO常用于Proactor. 目录 1. 服务器编程框架简介2. IO处理1. R…...

PySpark(三)RDD持久化、共享变量、Spark内核制度,Spark Shuffle
目录 RDD持久化 RDD 的数据是过程数据 RDD 缓存 RDD CheckPoint 共享变量 广播变量 累加器 Spark 内核调度 DAG DAG 的宽窄依赖和阶段划分 内存迭代计算 Spark是怎么做内存计算的? DAG的作用?Stage阶段划分的作用? Spark为什么比MapReduce快? Spar…...
详解MYSQL中的平均值组大小
文章目录 平均值组大小了解平均值组大小MySQL什么时候会使用平均值组大小平均值组大小对于索引选取的影响平均值组大小 了解平均值组大小 总数据量 / 值组 = 平均值组大小 值组是一组具有相同键前缀值的行,及所有相等的键为一个值组。总数据量为全表数据量MySQL什么时候会使…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...