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

react 10之状态管理工具2 redux + react-redux +redux-saga

目录

  • react 10之状态管理工具2 redux +
    • store / index.js 入口文件
    • actionType.js actions常量的文件
    • rootReducer.js 总的reducer 用于聚合所有模块的 reducer
    • rootSaga.js 总的saga 用于聚合所有模块的 saga
    • store / form / formActions.js 同步修改 isShow
    • store / form / formReducer.js 同步修改 isShow
    • store / list / listActions.js 同步与异步修改 count、arr
    • store / list / listReducer.js 同步与异步修改 count、arr
    • store / list / listSaga.js 同步与异步修改 count、arr ( 获取最新的count和arr )
    • store / test / testActions.js 被add的异步修改了数据
    • store / test / testReducer.js 被add的异步修改了数据
    • index.js 项目入口文件引入
    • 7redux/3使用saga/app.jsx
    • 效果

react 10之状态管理工具2 redux +

  • npm install redux react-redux

  • npm i redux-saga

  • redux-saga

    • redux-saga是一个Redux的中间件,它允许你在Redux中编写异步的action creators。

store / index.js 入口文件

import { applyMiddleware, legacy_createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from "./rootReducer";
import rootSaga from "./rootSaga";const sagaMiddleware = createSagaMiddleware();const store = legacy_createStore(rootReducer, applyMiddleware(sagaMiddleware));sagaMiddleware.run(rootSaga);export default store;

actionType.js actions常量的文件

// actionType.js 常量 唯一标识 标记当前action的唯一性
export const FORM_ADD_COUNT = 'form_addCount'
export const FORM_SUB_COUNT = 'form_subCount'
export const LIST_CHANGE_IsSHOW = 'list_change_isShow'export const TEST_CHANGE_ARR = 'test_change_arr'

rootReducer.js 总的reducer 用于聚合所有模块的 reducer

// rootReducer.js 总的reducer 用于聚合所有模块的 reducer
import { combineReducers } from 'redux';
import formReducer from './form/formReducer';
import listReducer from './list/listReducer';
import testReducer from './test/testReducer';const rootReducer = combineReducers({list: listReducer,form: formReducer,test: testReducer
});export default rootReducer;

rootSaga.js 总的saga 用于聚合所有模块的 saga

// rootSaga.js 总的saga 用于聚合所有模块的 saga
import { all } from 'redux-saga/effects';
import watchListActions from './list/listSaga';function* rootSaga() {yield all([watchListActions()]);
}export default rootSaga;

store / form / formActions.js 同步修改 isShow

// formActions.js
import { LIST_CHANGE_IsSHOW } from "../actionType";
export const list_changeShow = () => ({type: LIST_CHANGE_IsSHOW,
});

store / form / formReducer.js 同步修改 isShow

// formReducer.js
import { LIST_CHANGE_IsSHOW } from "../actionType";
const initialState = {isShow: false
};const formReducer = (state = initialState, action) => {switch (action.type) {case LIST_CHANGE_IsSHOW:return { ...state, isShow: !state.isShow };default:return state;}
};export default formReducer;

store / list / listActions.js 同步与异步修改 count、arr

// listActions.js
import { FORM_ADD_COUNT, FORM_SUB_COUNT } from "../actionType";
export const form_addCount = () => ({type: FORM_ADD_COUNT
});export const form_subCount = () => ({type: FORM_SUB_COUNT
});

store / list / listReducer.js 同步与异步修改 count、arr

// listReducer.js
import { FORM_ADD_COUNT, FORM_SUB_COUNT } from "../actionType";
const initialState = {count: 0
};const listReducer = (state = initialState, action) => {switch (action.type) {case FORM_ADD_COUNT:return { ...state, count: state.count + 1 };case FORM_SUB_COUNT:return { ...state, count: state.count - 1 };default:return state;}
};export default listReducer;

store / list / listSaga.js 同步与异步修改 count、arr ( 获取最新的count和arr )

// listSaga.js
import { delay, put, select, takeEvery } from 'redux-saga/effects';
import { FORM_ADD_COUNT, FORM_SUB_COUNT, TEST_CHANGE_ARR } from "../actionType";function* form_addCountAsync() {// 异步操作,例如发送网络请求等yield console.log('add count...',)// const currentCount = yield select((state) => state.list.count);// console.log('currentCount',currentCount); // 获取到count最新的值 可以用于发起异步请求啥的yield delay(2000); // 延迟2s后 再触发 TEST_CHANGE_ARRlet currentArrLength = yield select((state) => state.test.arr)currentArrLength = currentArrLength?.length  + 1console.log('currentArrLength',currentArrLength);yield put({ type: TEST_CHANGE_ARR ,payload:'我是-' + currentArrLength}); // 修改test模块的 arr数据
}function* form_subCountAsync() {// 异步操作,例如发送网络请求等yield console.log('sub count...');
}function* watchListActions() {yield takeEvery(FORM_ADD_COUNT, form_addCountAsync);yield takeEvery(FORM_SUB_COUNT, form_subCountAsync);
}export default watchListActions;

store / test / testActions.js 被add的异步修改了数据

// testActions.js
import { TEST_CHANGE_ARR } from "../actionType";
export const test_change_arr = () => ({type: TEST_CHANGE_ARR,
});

store / test / testReducer.js 被add的异步修改了数据

// testReducer.js
import { TEST_CHANGE_ARR } from "../actionType";
const initialState = {arr: []
};const testReducer = (state = initialState, action) => {console.log('action',action);switch (action.type) {case TEST_CHANGE_ARR:return { ...state, arr: [...state.arr,action.payload] };default:return state;}
};export default testReducer;

index.js 项目入口文件引入

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import App from "./7redux/3使用saga/app";
import store from "./store/index.js";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Provider store={store}><App /></Provider>
);

7redux/3使用saga/app.jsx

import React from 'react';
import { connect } from 'react-redux';
import { list_changeShow } from '../../store/form/formActions';
import { form_addCount, form_subCount } from '../../store/list/listActions';class App extends React.Component {render() {// console.log('this.props',this.props);const { count, isShow, form_subCount, form_addCount, list_changeShow,arr } = this.props;return (<div><p>Count: {count}</p><button onClick={form_addCount}>addcount</button><button onClick={form_subCount}>Decrement</button><p>isShow: {isShow ? 'True' : 'False'}</p><button onClick={list_changeShow}>Toggle Show</button><p>arr: {arr}</p></div>);}
}const mapStateToProps = (state) => ({count: state.list.count,isShow: state.form.isShow,arr: state.test.arr,
});const mapDispatchToProps = {form_addCount,form_subCount,list_changeShow
};export default connect(mapStateToProps, mapDispatchToProps)(App);

效果

在这里插入图片描述

相关文章:

react 10之状态管理工具2 redux + react-redux +redux-saga

目录 react 10之状态管理工具2 redux store / index.js 入口文件actionType.js actions常量的文件rootReducer.js 总的reducer 用于聚合所有模块的 reducerrootSaga.js 总的saga 用于聚合所有模块的 sagastore / form / formActions.js 同步修改 isShowstore / form / formRedu…...

gor工具http流量复制、流量回放,生产运维生气

gor是一款流量复制回放工具&#xff0c;gor工具的官网&#xff1a;https://goreplay.org/ 1、对某个端口的http流量进行打印 ./gor --input-raw :8000 --output-stdout 2、对流量实时转发&#xff0c;把81端口流量转发到192.168.3.221:80端口 ./gor --input-raw :81--output-ht…...

设计模式之单例设计模式

单例设计模式 2.1 孤独的太阳盘古开天&#xff0c;造日月星辰。2.2 饿汉造日2.3 懒汉的队伍2.4 大道至简 读《秒懂设计模式总结》 单例模式(Singleton)是一种非常简单且容易理解的设计模式。顾名思义&#xff0c;单例即单一的实例&#xff0c;确切地讲就是指在某个系统中只存在…...

Java自学到什么程度就可以去找工作了?

引言 Java作为一门广泛应用于软件开发领域的编程语言&#xff0c;对于初学者来说&#xff0c;了解到什么程度才能开始寻找实习和入职机会是一个常见的问题。 本文将从实习和入职这两个方面&#xff0c;分点详细介绍Java学习到什么程度才能够开始进入职场。并在文章末尾给大家安…...

三、Kafka生产者

目录 3.1 生产者消息发送流程3.1.1 发送原理 3.2 异步发送 API3.3 同步发送数据3.4 生产者分区3.4.1 kafka分区的好处3.4.2 生产者发送消息的分区策略3.4.3 自定义分区器 3.5 生产者如何提高吞吐量3.6 数据可靠性 3.1 生产者消息发送流程 3.1.1 发送原理 3.2 异步发送 API 3…...

【SA8295P 源码分析】19 - QNX Host NFS 文件系统配置

【SA8295P 源码分析】19 - QNX Host NFS 文件系统配置 一、NFS Server二、NFS Client三、NFS 相关的文件及目录四、将文件放入QNX 文件系统中五、编译下载验证系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》 本文链接:《【SA8295P 源码分析】19 - QNX Host N…...

JRE、JDK、JVM及JIT之间有什么不同?_java基础知识总结

当涉及Java编程和执行时&#xff0c;以下术语具有不同的含义&#xff1a; 1.JRE (Java Runtime Environment) JRE是Java运行时环境的缩写。它是一个包含用于在计算机上运行Java应用程序所需的组件集合。JRE包括了以下几个主要部分&#xff1a; Java虚拟机(JVM)&#xff1a;用…...

sqlite3数据库的实现

sqlite3代码实现数据库的插入、删除、修改、退出功能 #include <head.h> #include <sqlite3.h> #include <unistd.h> int do_insert(sqlite3 *db); int do_delete(sqlite3 *db); int do_update(sqlite3 *db);int main(int argc, const char *argv[]) {sqlit…...

c#设计模式-结构型模式 之 桥接模式

前言 桥接模式是一种设计模式&#xff0c;它将抽象与实现分离&#xff0c;使它们可以独立变化。这种模式涉及到一个接口作为桥梁&#xff0c;使实体类的功能独立于接口实现类。这两种类型的类可以结构化改变而互不影响。 桥接模式的主要目的是通过将实现和抽象分离&#xff0c;…...

【Vue-Router】导航守卫

前置守卫 main.ts import { createApp } from vue import App from ./App.vue import {router} from ./router // import 引入 import ElementPlus from element-plus import element-plus/dist/index.css const app createApp(App) app.use(router) // use 注入 ElementPlu…...

07无监督学习——降维

1.降维的概述 维数灾难(Curse of Dimensionality):通常是指在涉及到向量的计算的问题中&#xff0c;随着维数的增加&#xff0c;计算量呈指数倍增长的一种现象。 1.1什么是降维&#xff1f; 1.降维(Dimensionality Reduction)是将训练数据中的样本(实例)从高维空间转换到低维…...

系列七、IOC操作bean管理(xml自动装配)

一、概述 自动装配是根据指定规则&#xff08;属性名称或者属性类型&#xff09;&#xff0c;Spring自动将匹配的属性值进行注入。 二、分类 xml自动装配分为按照属性名称自动装配&#xff08;byName&#xff09;和按照属性类型自动装配&#xff08;byType&#xff09;。 2.1…...

01- vdom 和模板编译源码

组件渲染的过程 template --> ast --> render --> vDom --> 真实的Dom --> 页面 Runtime-Compiler和Runtime-Only的区别 - 简书 编译步骤 模板编译是Vue中比较核心的一部分。关于 Vue 编译原理这块的整体逻辑主要分三个部分&#xff0c;也可以说是分三步&am…...

C++入门知识点——解决C语言不足

&#x1f636;‍&#x1f32b;️Take your time ! &#x1f636;‍&#x1f32b;️ &#x1f4a5;个人主页&#xff1a;&#x1f525;&#x1f525;&#x1f525;大魔王&#x1f525;&#x1f525;&#x1f525; &#x1f4a5;代码仓库&#xff1a;&#x1f525;&#x1f525;魔…...

探秘分布式大数据:融合专业洞见,燃起趣味火花,启迪玄幻思维

文章目录 一 数据导论二 大数据的诞生三 大数据概论3.1 大数据的5V特征3.2 大数据的工作核心 四 大数据软件生态4.1 数据存储软件4.2 数据计算软件4.3 数据传输软件 五 Apache Hadoop概述5.1 Apache Hadoop框架5.2 Hadoop的功能5.3 Hadoop的发展5.4 Hadoop发行版本 一 数据导论…...

什么是 SPI,和API有什么区别?

面试回答 Java 中区分 API 和 SPI&#xff0c;通俗的讲&#xff1a;API 和 SPI 都是相对的概念&#xff0c;他们的差别只在语义上&#xff0c;API 直接被应用开发人员使用&#xff0c;SPI 被框架扩展人员使用。 API Application Programming Interface 大多数情况下&#xff…...

python3 安装clickhouse_sqlalchemy(greenlet) 失败

环境信息&#xff1a; centos7操作系统&#xff0c;python3.8 执行pip3 install clickhouse_sqlalchemy或者pip3 install greenlet报以下报错&#xff1a; Command "/opt/python3.6.10-customized/bin/python3.6 -u -c "import setuptools, tokenize;file/tmp/pip-in…...

五款拿来就能用的炫酷表白代码

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 五款炫酷表白代码 1、无限弹窗表白2、做我女朋友好吗&#xff0c;不同意就关机3、…...

Springboot 封装整活 Mybatis 动态查询条件SQL自动组装拼接

前言 ps&#xff1a;最近在参与3100保卫战&#xff0c;战况很激烈&#xff0c;刚刚打完仗&#xff0c;来更新一下之前写了一半的博客。 该篇针对日常写查询的时候&#xff0c;那些动态条件sql 做个简单的封装&#xff0c;自动生成&#xff08;抛砖引玉&#xff0c;搞个小玩具&a…...

宝塔部署Java+Vue前后端分离项目经验总结

前言 之前部署服务器都是在Linux环境下自己一点一点安装软件&#xff0c;听说用宝塔傻瓜式部署更快&#xff0c;这次浅浅尝试了一把。 确实简单&#xff01; 1、 买服务器 咋买服务器略&#xff0c;记得服务器装系统就装 Cent OS 7系列即可&#xff0c;我装的7.6。 2、创建…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...