React 全栈体系(十三)

第七章 redux

五、redux 异步编程

1. 理解

  • redux 默认是不能进行异步处理的,
  • 某些时候应用中需要在 redux 中执行异步任务(ajax, 定时器)

2. 使用异步中间件

  • npm install --save redux-thunk

3. 代码 - 异步 action 版

3.1 store
/* src/redux/store.js */
/*** 该文件专门用于暴露一个store对象,整个应用只有一个store对象*/
//引入createStore,专门用于创建redux中最为核心的store对象
import { createStore, applyMiddleware } from "redux";
//引入为Count组件服务的reducer
import countReducer from "./count_reducer";
//引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
//暴露store
export default createStore(countReducer, applyMiddleware(thunk));
3.2 count_action
/* src/redux/count_action.js */
/*** 该文件专门为Count组件生成action对象*/
import { INCREMENT, DECREMENT } from "./constant";//同步action,就是指action的值为Object类型的一般对象
export const createIncrementAction = (data) => ({ type: INCREMENT, data });
export const createDecrementAction = (data) => ({ type: DECREMENT, data });//异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的
export const createIncrementAsyncAction = (data, time) => {return (dispatch) => {setTimeout(() => {dispatch(createIncrementAction(data));}, time);};
};
3.3 Count
/* src/components/Count/index.jsx */
import React, { Component } from "react";
//引入store,用于获取redux中保存状态
import store from "../../redux/store";
//引入actionCreator,专门用于创建action对象
import {createDecrementAction,createIncrementAction,createIncrementAsyncAction,
} from "../../redux/count_action";export default class Count extends Component {//加法increment = () => {const { value } = this.selectNumber;store.dispatch(createIncrementAction(value * 1));};//减法decrement = () => {const { value } = this.selectNumber;store.dispatch(createDecrementAction(value * 1));};//奇数加incrementIfOdd = () => {const { value } = this.selectNumber;const count = store.getState();if (count % 2 !== 0) {store.dispatch(createIncrementAction(value * 1));}};//异步加incrementAsync = () => {const { value } = this.selectNumber;store.dispatch(createIncrementAsyncAction(value * 1, 500));};render() {return (<div><h1>当前求和为:{store.getState()}</h1><select ref={(c) => (this.selectNumber = c)}><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;<button onClick={this.incrementAsync}>异步加</button></div>);}
}
3.4 总结
(1).明确:延迟的动作不想交给组件自身,想交给action
(2).何时需要异步action:想要对状态进行操作,但是具体的数据靠异步任务返回。
(3).具体编码:1).yarn add redux-thunk,并配置在store中2).创建action的函数不再返回一般对象,而是一个函数,该函数中写异步任务。3).异步任务有结果后,分发一个同步的action去真正操作数据。
(4).备注:异步action不是必须要写的,完全可以自己等待异步任务的结果了再去分发同步action。

六、react-redux

在这里插入图片描述

1. 理解

  • 一个 react 插件库
  • 专门用来简化 react 应用中使用 redux

2. react-Redux 将所有组件分成两大类

2.1 UI 组件
  • 只负责 UI 的呈现,不带有任何业务逻辑
  • 通过 props 接收数据(一般数据和函数)
  • 不使用任何 Redux 的 API
  • 一般保存在 components 文件夹下
2.2 容器组件
  • 负责管理数据和业务逻辑,不负责 UI 的呈现
  • 使用 Redux 的 API
  • 一般保存在 containers 文件夹下
2.3 相关 API
2.3.1 Provider:让所有组件都可以得到 state 数据
<Provider store={store}><App />
</Provider>
2.3.2 connect:用于包装 UI 组件生成容器组件
import { connect } from 'react-redux'connect(mapStateToprops,mapDispatchToProps)(Counter)
2.3.3 mapStateToprops:将外部的数据(即 state 对象)转换为 UI 组件的标签属性
const mapStateToprops = function (state) {return {value: state}
}
2.3.4 mapDispatchToProps:将分发 action 的函数转换为 UI 组件的标签属性

3. 代码 - react-redux 的基本使用

  • 安装:npm install react-redux
3.1 index
/* src/index.js */
//引入react核心库
import React from "react";
//引入ReactDOM
import ReactDOM from "react-dom";
//引入App组件
import App from "./App";
import store from "./redux/store";ReactDOM.render(<App />, document.getElementById("root"));
//监测redux中状态的改变,如redux的状态发生了改变,那么重新渲染App组件
store.subscribe(() => {ReactDOM.render(<App />, document.getElementById("root"));
});
3.2 App
/* src/App.jsx */
import React, { Component } from "react";
import Count from "./containers/Count";
import store from "./redux/store";export default class App extends Component {render() {return (<div>{/* 给容器组件传递store */}<Count store={store} /></div>);}
}
3.3 Count(Component)
/* src/components/Count/index.jsx */
import React, { Component } from "react";export default class Count extends Component {//加法increment = () => {const { value } = this.selectNumber;this.props.jia(value * 1);};//减法decrement = () => {const { value } = this.selectNumber;this.props.jian(value * 1);};//奇数加incrementIfOdd = () => {const { value } = this.selectNumber;if (this.props.count % 2 !== 0) {this.props.jia(value * 1);}};//异步加incrementAsync = () => {const { value } = this.selectNumber;this.props.jiaAsync(value * 1, 500);};render() {return (<div><h1>当前求和为:{this.props.count}</h1><select ref={(c) => (this.selectNumber = c)}><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;<button onClick={this.incrementAsync}>异步加</button></div>);}
}
3.4 Count(Container)
/* src/containers/Count/index.jsx */
//引入Count的UI组件
import CountUI from "../../components/Count";
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction,
} from "../../redux/count_action";//引入connect用于连接UI组件与redux
import { connect } from "react-redux";/*1.mapStateToProps函数返回的是一个对象;2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value3.mapStateToProps用于传递状态
*/
function mapStateToProps(state) {return { count: state };
}/*1.mapDispatchToProps函数返回的是一个对象;2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value3.mapDispatchToProps用于传递操作状态的方法
*/
function mapDispatchToProps(dispatch) {return {jia: (number) => dispatch(createIncrementAction(number)),jian: (number) => dispatch(createDecrementAction(number)),jiaAsync: (number, time) =>dispatch(createIncrementAsyncAction(number, time)),};
}
//使用connect()()创建并暴露一个Count的容器组件
export default connect(mapStateToProps, mapDispatchToProps)(CountUI);
3.5 总结
(1).明确两个概念:1).UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。2).容器组件:负责和redux通信,将结果交给UI组件。
(2).如何创建一个容器组件————靠 react-redux 的 connect函数connect(mapStateToProps,mapDispatchToProps)(UI组件)-mapStateToProps:映射状态,返回值是一个对象-mapDispatchToProps:映射操作状态的方法,返回值是一个对象
(3).备注1:容器组件中的store是靠props传进去的,而不是在容器组件中直接引入
(4).备注2:mapDispatchToProps,也可以是一个对象

4. 代码 - 优化 1:简写 mapDispatch

Count(Container)
/* src/containers/Count/index.jsx */
//引入Count的UI组件
import CountUI from "../../components/Count";
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction,
} from "../../redux/count_action";//引入connect用于连接UI组件与redux
import { connect } from "react-redux";//使用connect()()创建并暴露一个Count的容器组件
export default connect((state) => ({ count: state }), {jia: createIncrementAction,jian: createDecrementAction,jiaAsync: createIncrementAsyncAction,
})(CountUI);

5. 代码 - 优化 2:Provider 组件的使用

5.1 index
/* src/index.js */
//引入react核心库
import React from "react";
//引入ReactDOM
import ReactDOM from "react-dom";
//引入App组件
import App from "./App";
import store from "./redux/store";
import { Provider } from "react-redux";ReactDOM.render(<Provider store={store}><App /></Provider>,document.getElementById("root")
);
5.2 App
/* src/App.jsx */
import React, { Component } from "react";
import Count from "./containers/Count";export default class App extends Component {render() {return (<div><Count /></div>);}
}

6. 代码 - 优化 3:整合 UI 组件和容器组件

6.1 Count(Container)
/* src/containers/Count/index.jsx */
import React, { Component } from "react";
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction,
} from "../../redux/count_action";//引入connect用于连接UI组件与redux
import { connect } from "react-redux";// 定义UI组件
class Count extends Component {//加法increment = () => {const { value } = this.selectNumber;this.props.jia(value * 1);};//减法decrement = () => {const { value } = this.selectNumber;this.props.jian(value * 1);};//奇数加incrementIfOdd = () => {const { value } = this.selectNumber;if (this.props.count % 2 !== 0) {this.props.jia(value * 1);}};//异步加incrementAsync = () => {const { value } = this.selectNumber;this.props.jiaAsync(value * 1, 500);};render() {return (<div><h1>当前求和为:{this.props.count}</h1><select ref={(c) => (this.selectNumber = c)}><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;<button onClick={this.incrementAsync}>异步加</button></div>);}
}//使用connect()()创建并暴露一个Count的容器组件
export default connect((state) => ({ count: state }), {jia: createIncrementAction,jian: createDecrementAction,jiaAsync: createIncrementAsyncAction,
})(Count);
6.2 总结
(1).容器组件和UI组件整合一个文件
(2).无需自己给容器组件传递store,给<App/>包裹一个<Provider store={store}>即可。
(3).使用了react-redux后也不用再自己检测redux中状态的改变了,容器组件可以自动完成这个工作。
(4).mapDispatchToProps也可以简单的写成一个对象
(5).一个组件要和redux“打交道”要经过哪几步?(1).定义好UI组件---不暴露(2).引入connect生成一个容器组件,并暴露,写法如下:connect(state => ({key:value}), //映射状态{key:xxxxxAction} //映射操作状态的方法)(UI组件)(3).在UI组件中通过this.props.xxxxxxx读取和操作状态

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

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

相关文章

【Spatial-Temporal Action Localization(七)】论文阅读2022年

文章目录 1. TubeR: Tubelet Transformer for Video Action Detection摘要和结论引言&#xff1a;针对痛点和贡献模型框架TubeR Encoder&#xff1a;TubeR Decoder&#xff1a;Task-Specific Heads&#xff1a; 2. Holistic Interaction Transformer Network for Action Detect…

前端项目练习(练习-001-纯原生)

先创建一个空文件夹&#xff0c;名字为web-001,然后用idea开发工具打开&#xff0c;如图&#xff1a; 可以看到&#xff0c;这是个彻底的空项目&#xff0c;创建 index.html index.js index.css三个文件&#xff0c;如图&#xff1a; 其中&#xff0c;html文件内容如下&am…

Qt Charts简介

文章目录 一.图标类型Charts分类1.折线图和样条曲线图2.面积图和散点图3.条形图4.饼图5.误差棒图6.烛台图7.极坐标图 二.坐标轴Axes类型分类三.图例四.图表的互动五.图表样式主题 一.图标类型Charts分类 图表是通过使用系列类的实例并将其添加到QChart或ChartView实例来创建的…

RT-Thread(学习)

RT-Thread是一款完全由国内团队开发维护的嵌入式实时操作系统&#xff08;RTOS&#xff09;&#xff0c;具有完全的自主知识产权。经过16个年头的沉淀&#xff0c;伴随着物联网的兴起&#xff0c;它正演变成一个功能强大、组件丰富的物联网操作系统。 RT-Thread概述 RT-Threa…

基于 SpringBoot+Vue的电影影城管理系统,附源码,数据库

文章目录 第一章 简介第二章 技术栈第三章 功能分析第四章 系统设计第5章 系统详细设计六 源码咨询 第一章 简介 本影城管理系统&#xff0c;是基于 Java SpringBoot 开发的。主要包括二大功能模块&#xff0c;即用户功能模块和管理员功能模块。 &#xff08;1&#xff09;管…

渗透测试信息收集方法和工具分享

文章目录 一、域名收集1.OneForAll2.子域名挖掘机3.subdomainsBurte4.ssl证书查询 二、获取真实ip1.17CE2.站长之家ping检测3.如何寻找真实IP4.纯真ip数据库工具5.c段&#xff0c;旁站查询 三、端口扫描1.端口扫描站长工具2.masscan(全端口扫描)nmap扫描3.scanport4.端口表5.利…

【力扣每日一题】2023.9.23 树上的操作

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 这是一道程序设计类的题目&#xff0c;题目比较长&#xff0c;我稍微概括一下。 构造函数中给我们一个数组&#xff0c;第i个元素表示第…

最新Python大数据之Excel进阶

文章目录 Excel图表类型了解有哪些图表类型 Excel图表使用图表的创建方式利用固定数据区域创建图表编辑数据系列添加数据标签格式化图表 Excel数据透视表数据透视表对原始数据的要求创建数据透视表数据透视表字段布局将数据透视图变成普通图表 Excel图表类型 为了揭示数据规律…

如何模拟自然界生态系统中的食物链

本人最近在研究一款针对青少年儿童的教育游戏&#xff0c;希望从培养孩子各方面的综合素质出发&#xff0c;引导孩子掌握多方面的软知识&#xff0c;软技能。其中有一个比较新颖的游戏玩法------打猎。该玩法创新点在于&#xff0c;引入了食物链的概念。过去一般的游戏里&#…

时间复杂度、空间复杂度

一、时间复杂度 1、概念 时间复杂度&#xff1a;计算的是当一个问题量级增加的时间&#xff0c;时间增长的趋势&#xff1b; O&#xff08;大O表示法&#xff09;&#xff1a;渐进的时间复杂度 2、举例 ① 以下 for 循环的时间复杂度&#xff1a;O(1 3n) O(n) 去掉常数…

查看吾托帮88.47的docker里的tomcat日志

步骤如下 &#xff08;1&#xff09;ssh &#xff08;2&#xff09;ssh root192.168.88.47 等待输入密码&#xff1a;fytest &#xff08;3&#xff09;pwd #注释&#xff1a;输出/root &#xff08;4&#xff09;docker exec -it wetoband_deploy /bin/bash #注释&#xff1…

nginx实现反向代理实例

1 前言 1.1 演示内容 在服务器上访问nginx端口然后跳转到tomcat服务器 1.2 前提条件 前提条件&#xff1a;利用docker安装好nginx、tomcat、jdk8&#xff08;tomcat运行需要jdk环境&#xff09; 只演示docker安装tomcat&#xff1a; 默认拉取最新版tomcat docker pull t…

【vue2第二十章】vuex使用 (state,mutations,actions,getters)

vuex是什么&#xff1f; Vuex是一个用于Vue.js应用程序的状态管理模式。它允许您在应用程序中管理共享状态&#xff0c;并以可预测的方式进行状态更新。Vuex集成了Vue的响应式系统&#xff0c;使得状态的变化能够自动地更新视图。使用Vuex&#xff0c;您可以将应用程序的状态集…

【论文阅读 07】Anomaly region detection and localization in metal surface inspection

比较老的一篇论文&#xff0c;金属表面检测中的异常区域检测与定位 总结&#xff1a;提出了一个找模板图的方法&#xff0c;使用SIFT做特征提取&#xff0c;姿态估计看差异有哪些&#xff0c;Hough聚类做描述符筛选&#xff0c;仿射变换可视化匹配图之间的关系&#xf…

如何使用ArcGIS Pro自动矢量化道路

对于已经制作好的电子地图&#xff0c;我们可以通过像素识别的方式将其中的要素提取出来&#xff0c;比如本教程要讲到的道路数据&#xff0c;这里为大家介绍一下在ArcGIS Pro中如何自动矢量化道路&#xff0c;希望能对你有所帮助。 栅格计算 在工具箱中点击“Spatial Analys…

【AIGC】Llama2-7B-Chat模型微调

环境 微调框架&#xff1a;LLaMA-Efficient-Tuning 训练机器&#xff1a;4*RTX3090TI (24G显存) python环境&#xff1a;python3.8, 安装requirements.txt依赖包 一、Lora微调 1、准备数据集 2、训练及测试 1&#xff09;创建模型输出目录 mkdir -p models/llama2_7b_chat…

unity gb28181 rtsp 视频孪生图像拉流和矫正插件(一)

目的是为了视频孪生&#xff0c;将视频放到三维里面&#xff0c;如果使用自己写的插件&#xff0c;有更好的灵活性&#xff0c;同时断线重连等等都更好控制了。 1、矫正算法和硬件解码 最好使用opencv制作&#xff0c;可以使用opencv的cuda加速&#xff0c;opencv的编译&…

面试题:RocketMQ 如何保证消息不丢失,如何保证消息不被重复消费?

文章目录 1、消息整体处理过程Producer发送消息阶段手段一&#xff1a;提供SYNC的发送消息方式&#xff0c;等待broker处理结果。手段二&#xff1a;发送消息如果失败或者超时&#xff0c;则重新发送。手段三&#xff1a;broker提供多master模式&#xff0c;即使某台broker宕机…

聚观早报 | 杭州亚运开幕科技感拉满;腾讯官宣启动「青云计划」

【聚观365】9月25日消息 杭州亚运开幕科技感拉满 腾讯官宣启动「青云计划」 FF任命新全球CEO 比亚迪夺得多国销冠 iPhone 15/15 Pro销售低于预期 杭州亚运开幕科技感拉满 杭州第19届亚洲运动会开幕式23日晚在杭州奥体中心主体育馆举行&#xff0c;这届开幕式可谓科技感拉…

基于Yolov8的野外烟雾检测(2):多维协作注意模块MCA,效果秒杀ECA、SRM、CBAM等 | 2023.9最新发布

目录 1.Yolov8介绍 2.野外火灾烟雾数据集介绍 3.MCA介绍 4.训练结果分析 5.系列篇 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它建立在先前…