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

Redux 学习笔记

在使用 React Redux 前,我们首先了解一下 Redux 的一些基础知识。

Redux 是 JavaScript 应用程序中用于状态管理的容器。它不依赖于任何框架,可以与任何 UI 库和框架一起使用。在应用程序中使用 Redux 时,Redux 是以可预测的方式管理状态。

Redux 的核心概念

  1. Store

应用系统中需要管理的数据,全部集中在这里

  1. Action

数据的处理都存放在这里,例如数据的添加、删除操作等

  1. Reducer

数据接收和转换存放在这里

Store、Action 和 Reducer 的三者关系

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Redux 的使用原则

  1. 应用程序的状态存储形式是单个对象树

  2. 状态的获取必须通过Action来执行,在Action中我们存放着对应很多动作的key,我们只有执行对应的动作后才能拿到数据

  3. 拿到的数据必须通过Reducer来转换状态树的数据,而Reducer在执行时会拿到Action对应的动作,并接受返回的数据然后进行处理

Actions 说明

Action 的创建如下:

// 定义一个action
function buyCake() {return {type: BUY_CAKE,info: "First redux action",};
}

从上述的创建过程来看,action 其实是一个函数并且返回一个对象,其中返回的对象必须带有type属性,这个属性在后续调用的时候会用到。

其次就是除了type属性外,我们还可以根据自己的业务需求来扩展action的属性。

Reducers 说明

Reducers 是专门负责接受状态并且执行对应的action,并把执行完成后跟新对应的状态。

定义一个 Reducer 的过程很简单,具体代码如下:

// 定义一个 state
const initialState = {numOfCakes: 20,
};// 定义一个 reducer
const reducer = (state = initialState, action) => {switch (action.type) {case BUY_CAKE:return {numOfCakes: state.numOfCakes - 1,};default:return state;}
};

从上述的代码中可以看出Reducer本质也是一个函数,并且接受两个函数。其中第一个参数是Store,而第二个参数是action,并且通过 type 来决定对状态执行什么操作。

Store 说明

Store 的职责主要包括如下几点:

  1. 负责保存应用程序状态
  2. 对外暴露getState的方法,通过此方法可以获取到应用程序中的状态值
  3. 提供了一个dispatch(action)的方法,主要是用于调度对应的action,从而修改状态值
  4. 提供了一个注册监听器的方法subscribe(listener),每当状态发生改变的时候都会触发此函数
  5. 提供了一个取消监听器的方法,用于收回已注册的监听器

实现Store的过程如下:

const redux = require("redux");
const createStoreFn = redux.createStore; // 已经过时,这里只是展示概念性的东西,所以采用了旧方法
const store = createStoreFn(reducer); // 管理对应的状态
console.log(store.getState()); // 使用对外暴露获取状态数据的方法// 注册监听器
const unsubscribe = store.subscribe(() =>console.log("update state", store.getState())
);// 调用对应的 action 方法
store.dispatch(buyCake());
store.dispatch(buyCake());
store.dispatch(buyCake());unsubscribe();

如何实现多个 Reducers

只用一个 Reducers 来管理状态

function buyIceCream() {return {type: BUY_ICECREAM,};
}// 定义一个 State
const initialState = {numOfCakes: 20,numOfIceCream: 20,
};// 定义一个 reducer
const reducer = (state = initialState, action) => {switch (action.type) {case BUY_CAKE:return {...state,numOfCakes: state.numOfCakes - 1,};case BUY_ICECREAM:return {...state,numOfIceCream: state.numOfIceCream - 1,};default:return state;}
};

通过上述的实例代码可以看出,我们只是简单的添加了一个actionReducer就需要添加一个对应的状态处理方法,假如我们的业务逻辑比较复杂的话Reducer则会变得非常难以维护,所以我们可以使用多个Reducer来分解对状态处理的方法。

实现多个 Reducers

在实现多个 Reducers 的时候,我们需要用到combineReducers来帮我们注册对应的Rducer。具体的代码实例如下:

const initialCakeState = {numOfCakes: 20,
};
const initialIceCreamState = {numOfIceCream: 20,
};const cakeReducer = (state = initialCakeState, action) => {switch (action.type) {case BUY_CAKE:return {...state,numOfCakes: state.numOfCakes - 1,};default:return state;}
};const iceCreamReducer = (state = initialIceCreamState, action) => {switch (action.type) {case BUY_ICECREAM:return {...state,numOfIceCream: state.numOfIceCream - 1,};default:return state;}
};const rootReducer = combineReducers({cake: cakeReducer,iceCream: iceCreamReducer,
});
const store = createStoreFn(rootReducer);
const unsubscribe = store.subscribe(() =>console.log("update state", store.getState())
);
console.log(store.getState());// 调用对应的 action 方法
store.dispatch(buyCake());
store.dispatch(buyCake());
store.dispatch(buyCake());store.dispatch(buyIceCream());
store.dispatch(buyIceCream());unsubscribe();

如何实现异步 Actions

上述的操作都是同步的,而接下来我们来实现一下异步的Actions

我们以获取用户列表数据为例一步一步实现异步 Actions。

  1. 定义State

因为要实现异步的 Actions,所以我们的数据获取和处理会有一定处理时间,所以对应的State属性应该包括如下几个属性:loadinguserserror。具体代码如下:

const initialState = {loading: false, // 判断是否已经获取到数据users: [],error: "",
};
  1. 实现对应的 Actions

有了对应的状态数据,我们就可以编写一些对应的 Action 功能。具体的实例代码如下:

const FETCH_USERS_REQUEST = "FETCH_USERS_REQUEST";
const FETCH_USERS_SUCCESS = "FETCH_USERS_SUCCESS";
const FETCH_USERS_FAILURE = "FETCH_USERS_FAILURE";const fetchUsersRequest = () => {return {type: FETCH_USERS_REQUEST,};
};const fetchUserSuccess = (users) => {return {type: FETCH_USERS_SUCCESS,payload: users,};
};const fetchUserFaikuer = (error) => {return {type: FETCH_USERS_FAILURE,payload: error,};
};
  1. 实现对应的 Reducer

有了状态和执行动作,我们就可以实现对应的 Reducer。具体的代码如下:

const reducer = (state = initialState, action) => {switch (action.type) {case FETCH_USERS_REQUEST:return {...state,lading: true,};case FETCH_USERS_SUCCESS:return {loading: false,users: action.payload,error: "",};case FETCH_USERS_FAILURE:return {loading: false,users: [],error: action.payload,};}
};
  1. StateActionsReducer建立关系

有了上述的准备,现在我们就可以把这三个元素建立关系。

在建立关系之前我们需要安装两个工具:

npm install axios redux-thunk

我们使用 redux 的中间件来实现异步的数据获取。具体代码如下:

const appluMiddleware = redux.applyMiddleware;
const thunkMiddleware = require("redux-thunk").default;
const axios = require("axios");const store = createStoreFn(reducer, appluMiddleware(thunkMiddleware));const fetchUsers = () => {return function (dispatch) {dispatch(fetchUsersRequest());axios.get("https://jsonplaceholder.typicode.com/users").then((response) => {console.log(response);const users = response.data.map((user) => user.id);dispatch(fetchUserSuccess(users));}).catch((error) => {dispatch(fetchUserFaikuer(error.message));});};
};store.subscribe(() => {console.log(store.getState());
});
store.dispatch(fetchUsers());

相关文章:

Redux 学习笔记

在使用 React Redux 前,我们首先了解一下 Redux 的一些基础知识。 Redux 是 JavaScript 应用程序中用于状态管理的容器。它不依赖于任何框架,可以与任何 UI 库和框架一起使用。在应用程序中使用 Redux 时,Redux 是以可预测的方式管理状态。 …...

【Bug】8086汇编学习

文章目录 随笔Bug1、masm编译报错:Illegal use of register2、debug中使用段前缀3、[idata]在编译器中的处理4、push立即数报错5、报错:improper operand type6、程序莫名跳转到未知位置 (doing)7、DOSBox失去响应8、程序运行显示乱码9、程序运行导致DOS…...

JetBrains系列IDE全家桶激活

jetbrains全家桶 正版授权,这里有账号授权的渠道: https://www.mano100.cn/thread-1942-1-1.html 附加授权后的一张图片...

洛谷p1618三连击

import java.util.Scanner; //将 1-9 共9个数分成3组,分别组成3个三位数,且使这3个三位数构成A:B:C的比例,试求出所有满足条件的3个三位数。不满足输出“No!!!”。 public class Main {public static void main(String[] args) {Scanner sc …...

微信公众号h5写一个全局调用微信分享功能

1. 首先先安装依赖 npm install weixin-js-sdk --save 2. app.vue文件 <script> export default { onLaunch: function(e) {}, onShow: function(e) { console.log(App Show页面初始); // 路由参数存缓存的 这是为了防止他…...

聊聊精益需求的产生过程

这是鼎叔的第七十八篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本公众号《敏捷测试转型》&#xff0c;星标收藏&#xff0c;大量原创思考文章陆续推出。本人新书《无测试组织-测试团队的敏捷转型》​​​​​​​​​​​​​​已出版&#xff…...

Linux - 还不懂 gdb 调试器?(调试软件)

前言 当前&#xff0c;我们可以使用 make/makefile 来程序化执行代码文件&#xff1b;可以使用 gcc/g 等编译器来编译代码&#xff1b;可以使用 vim 编辑器来编写代码&#xff1b;其实在 Linux 当中还有一个工具&#xff0c;可以实现调试工作&#xff0c;这个工具就是 -- gdb。…...

Linux:程序地址空间/虚拟地址等相关概念理解

文章目录 程序地址空间虚拟地址和物理地址地址的转换地址空间是什么&#xff1f; 程序地址空间 在C和C程序中&#xff0c;一直有一个观点是&#xff0c;程序中的各个变量等都会有一定的地址空间&#xff0c;因此才会有诸如取地址&#xff0c;通过地址访问等操作&#xff0c;那…...

Python之爬虫

目录 HTTP请求HTTP响应获得页面响应伪装用户访问打包数据爬取豆瓣top250 HTTP请求 HTTP&#xff1a;HypertextTransferProtcol 超文本传输协议 1、请求行 POST/user/info?new_usertrue HTTP/1.1#资源了路径user/info 查询参数new_usertrue 协议版本HTTP/1.1 2、请求头 Ho…...

打造自己的前端组件库(奶妈版,超详细)

打造自己的前端组件库 demo是开源的&#xff0c;自己上npm 或者 github 上都能搜到 新建vue项目(sass js vue2) vue create yt-ui 修改文件目录(如下) 修改&#xff1a; 1.src 更名 examples; 2. src/components移动到项目最外层&#xff1b;3.vue.config.js更改入口文件 /…...

6.调制阶数相关

1、调制阶数与峰均比的关系 调制阶数&#xff08;modulation order&#xff09;对峰均比&#xff08;有一定的影响。 峰均比是用于衡量调制信号或波形在幅度上的动态范围的指标。它表示信号的最大峰值与平均功率之间的比值。较高的峰均比可能导致信号在传输或放大过程中出现过…...

Maven多模块管理(转载)

注意&#xff1a;父模块需设定打包方式为pom https://cloud.tencent.com/developer/article/1667275 dependencyManagement 统一管理子类依赖版本 在父类maven中加入&#xff0c;不会继承给子类&#xff0c;只能规定子类的依赖版本&#xff0c;子类加入dependence后无需写入 …...

运维学习CentOS 7进行Nightingale二进制部署

.因为Nightingale需要MySQL保存一些数据&#xff0c;所以可以参考《CentOS 7.6使用mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar安装Mysql 8.0》部署MySQL。 https://github.com/ccfos/nightingale/releases是可以github上下载Nightingale二进制安装包。 https://n9e.github.io/…...

安装Docker

本安装教程参考Docker官方文档&#xff0c;地址如下&#xff1a;https://docs.docker.com/engine/install/centos/ 卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \ docker-client \ docker-client-latest \ docker-common…...

【uniapp/uView】解决消息提示框悬浮在下拉框之上

需要实现这样的效果&#xff0c;即 toast 消息提示框在 popup 下拉框之上&#xff1a; 解决方法&#xff0c;把 <u-toast ref"uToast" /> 放在 u-popup 里面即可&#xff0c;这样就可以提升 toast 的优先级&#xff1a; <!-- 弹出下拉框 --><u-popu…...

有效管理token,充分发挥ChatGPT的能力

目录 给提供了 Token 的计算工具,来理解一下Token的计算方式,网址如下: 窗口如下: 实际消耗 Token 数量为 59个,换算之后为2.1-2.2的比例,即一个汉字消耗2.12.2个Token, 再测一下英文的Token消耗,包含空格在内,一共52个英文字母,消耗Token 13个,正好对应13个单词,…...

Python —— 验证码的处理执行JavaScript语句

1、验证码的处理 1、概述&绕过验证码的方案 很多的网站都在登录页面加入了识别文字&#xff0c;识别图片&#xff0c;拖动拼图的验证码方式来防止爬虫、恶意注册 等&#xff0c;如果是做自动化&#xff0c;需要绕过验证码才能进入下一步操作&#xff0c;那么有4种方案可以…...

MS12_020 3389远程溢出漏洞

1.search ms12_020 搜索ms12_020 2.use auxiliary/scanner/rdp/ms12_020_check 检查是否存在ms12_020漏洞 show options 查看所需参数 set RHOSTS x.x.x.x 设置目标IP地址 run 执行 检测出来有Ms12_020漏洞 3.use auxiliary/dos/windows/rdp/ms12_020_maxchannelids 选择…...

Pytorch ddp切换forward函数 验证ddp是否生效

DDP及其在pytorch中应用 ddp默认调用forward函数&#xff0c;有些模型无法使用forward函数&#xff0c;可以对模型包装一下。 class modelWraper(nn.Module):def __init__(self, model):super().__init__()self.model modeldef forward(self, *args, **kwargs):return self.…...

C++中按引用向函数传递参数

C中按引用向函数传递参数 在参数传递过程中&#xff0c;如果实参与引用参数不匹配&#xff0c;C将生成临时变量。当前&#xff0c;仅当参数为 const 引用时&#xff0c;C才允许这么做&#xff0c;但以前不 是这样。如果引用参数是 const&#xff0c;则编译器将在下面两种情况…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

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

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

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...