React整理总结(五、Redux)

news2024/10/6 8:37:23

1.Redux核心概念

纯函数
  • 确定的输入,一定会产生确定的输出;
  • 函数在执行过程中,不能产生副作用
store

存储数据

action

更改数据

reducer

连接store和action的纯函数
将传入的state和action结合,生成一个新的state

  • dispatch派发action修改store
  • subscribe | unsubscribe订阅store的数据发生变化
// store/index.js
import { createStore } from 'redux';

const initState = {
	msg: "hello redux"
}
/*** 定义reducer,纯函数*****/
function reducer(state = initState, action){
	if (action.type === "change"){
		return {...state, msg: action.payload.msg};
	}
	return state;
}

export default const store = createStore(reducer);


// store/ actionCreator.js
/**** 动态生成action *****/
export const CHANGEMSGACTION = msg => ({type: 'change', payload: {msg}});

// 使用的地方
import store from "~/store";
const unsubscribe = store.subscribe(() => {
	console.log("::::STORE", store.getState());
})
unsubscribe();

// 修改store中的数据
const MSGAction = {
	type: "change", 
	payload: {
		msg: "hello change",
	}
};
store.dispatch(MSGAction);
  • combineReducer将多个reducer合并为一个reducer,达到拆分store的目的

2. Redux三大原则

单一数据源
  • 整个应用程序的state被存储在一颗object tree中,并且这个object tree只存储在一个 store中:
  • R-edux并没有强制让我们不能创建多个Store,但是那样做并不利于数据的维护;
  • 单一的数据源可以让整个应用程序的state变得方便维护、追踪、修改;
State是只读的
  • 唯一修改State的方法一定是触发action,不要试图在其他地方通过任何的方式来修改State:
  • 这样就确保了View或网络请求都不能直接修改state,它们只能通过action来描述自己想要如何修改state;
  • 这样可以保证所有的修改都被集中化处理,并且按照严格的顺序来执行,所以不需要担心race condition(竟态)的问题;
使用纯函数来执行修改
  • 通过reducer将 旧state和 actions联系在一起,并且返回一个新的State:
  • 随着应用程序的复杂度增加,我们可以将reducer拆分成多个小的reducers,分别操作不同state tree的一部分;
  • 但是所有的reducer都应该是纯函数,不能产生任何的副作用;
    在这里插入图片描述

3.react-redux的使用

  • 通过provider给整个app提供store
// App.jsx
import { Provider } from 'react-redux';
import store from '~/store';

const root = document.querySelector("#root");
root.render(
	<Provider store={store}>
		<App/>
	</Provider>
)
  • 通过connect将组件和store连接。connect会返回一个高阶组件,接受的参数将store中的部分数据映射到组件
// 组件中
import React, { PureComponent } from "react";
import { connect } from "react-redux";

class MyComp extends PureComponent{
	render(){
		const { msg, changeMsg } = this.props;
		return (<div>
		<h2>{msg}</h2>
		<input onChange={val => changeMsg(val)} />
		</div>
	}
}
/**** 将state映射到props,组件中props中就会有msg ****/
function mapStateToProps(state){
	return {
		msg: state.msg
	}
}
/*** 将修改store的函数添加到组件的props中 ***/
function mspDispatchToProps(dispatch){
	return {
		changeMsg(msg){
			dispatch(CHANGEMSGACTION(msg));
		}
	}
}

export default connect(mapStateToProps, mapDispatchToProps)(MyComp);

  • 异步action—中间件
    • Middleware可以帮助我们在请求和响应之间嵌入一些操作的代码,比如cookie解析、日志记录、文件压缩等操作
    • createStore的第二个参数接受一个中间件,使用react-thunk使得dispatch可以派发函数,在派发的函数中可以异步更新store。
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

const reducer = (state, action) => {
	...
	return state;
}

const store = createStore(reducer, applyMiddleware(thunk));

// actionCreator.js
...
/**** 被派发的函数,需要返回一个函数,该函数接受两个参数dispatch,getState,*****/
const fetchHomeDataAction = () => {

	return (dispatch, getState) => {
		fetch(url).then(res => {
			dispatch(HOMEDATAACTION(res.data));
		});
	}
}
// 组件中
function mapDispatchToProps(dispatch){
	return {
		fetchHomeData(){
			dispatch(fetchHomeDataAction()); // 执行action函数
		}
	}
}
  • 使用redux-thunk
    • 在创建store时传入应用了middleware的enhance函数
      通过applyMiddleware来结合多个Middleware, 返回一个enhancer;将enhancer作为第二个参数传入到createStore中;
    • 定义返回一个函数的action:
      这里不是返回一个对象了,而是一个函数;该函数在dispatch之后会被执行;

4.Redux/toolkit

npm install @reduxjs/toolkit react-redux

  • createSlice({name, initialState, reducers:{}})接受reducer函数的对象、切片名称和初始状态值,并自动生成切片reducer,并带有相应的actions。
    • name:用户标记slice的名词, 在之后的redux-devtool中会显示对应的名词;
    • initialState:初始化值. 第一次初始化时的值;
    • reducers:相当于之前的reducer函数.对象类型,并且可以添加很多的函数;函数类似于redux原来reducer中的一个case语句;
      • 参数一:state
      • 参数二:调用这个action时,传递的action参数;
import { createSlice } from '@reduxjs/toolkit';
const CounterSlice = createSlice({
	name: "counter",
	initialState: {
		count: 0,
	},
	reducers: {
		addNumber(state, action){
			state.counter += action.payload;
		}
	}
});

export const { addNumber } = CounterSlice.action;
export default CounterSlice.reducer;
  • configureStore包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合你的 slice reducer,添加你提供的任何 Redux 中间件,redux-thunk默认包含,并启用 Redux DevTools Extension。
const store = configureStore({
	reducer: {
		counter: counterReducer;
	}
})
  • createAsyncThunk接受一个动作类型字符串和一个返回承诺的函数,并生成一个pending/fulfilled/rejected基于该承诺分派动作类型的 thunk
const AXIOSDataSlice = createSlice({
	name: 'axiosdata',
	initialState: {
		data: []
	},
	reducers: {
		setData(state, action){
			state.data = action.payload;
		}
	},
	extraReducers: {
		/**
		[AxiosMultidataAction.pending](state, action){
			state.data = action.payload;
		}
		[AxiosMultidataAction.rejected](state, action){
			state.data = action.payload;
		}
		**/
		[AxiosMultidataAction.fulfilled](state, action){
			state.data = action.payload;
		}
	}
	/*** 链式写法 *****/
	extraReducers: (builder) => {
		builder.addCase(AxiosMultidataAction.pending, (state, action) => {
			console.log("pending");	
		}).addCase(AxiosMultidataAction.fulfilled, (state, action) => {})
	}
})
export default AXIOSDataSlice.reducer;


const AxiosMultidataAction = createAsyncThunk("axiosdata", async (extraInfo, store) => {
// 第一个can
	const res = await getData();
	return res;
})
  • immerjs库保持数据不可变(持久化数据

5 手写connect

function connect(mapStateToProps, mapDispatchToProps){
	function hoc(Component){
		class HOCComponent extends PureComponent{
			constuctor(props){
				super(props);
				this.state = mapStateToProps(store.getState());
			}
			componentDidMount(){
				this.unsubscribe = store.subscribe(() => {
					//this.forceUpdate();
					this.setState(mapStateToProps(store.getState());
				})
			}
			componentWillUnmount() {
				this.unsubscribe();
			}
			
			render(){
				return <Component {...this.props} {...mapStateToProps(store.getState())} {...mapDispatchToProps(store.dispatch)} />
			}
		}
		return HOCComponent;
	}
	return hoc;
}

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

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

相关文章

Azure 机器学习 - 搜索中的检索增强 (RAG)

目录 一、Azure AI 信息检索系统介绍二、采用 Azure AI 搜索的 RAG 方法三、适合 Azure AI 搜索的自定义 RAG 模式四、Azure AI 搜索中的可搜索内容五、Azure AI 搜索中的内容检索构建查询响应按相关性排名适用于 RAG 方案的 Azure AI 搜索查询的示例代码 六、集成代码和 LLM七…

时间序列预测实战(十七)PyTorch实现LSTM-GRU模型长期预测并可视化结果(附代码+数据集+详细讲解)

一、本文介绍 本文给大家带来的实战内容是利用PyTorch实现LSTM-GRU模型&#xff0c;LSTM和GRU都分别是RNN中最常用Cell之一&#xff0c;也都是时间序列预测中最常见的结构单元之一&#xff0c;本文的内容将会从实战的角度带你分析LSTM和GRU的机制和效果&#xff0c;同时如果你…

Three.js相机模拟

有没有想过如何在 3D Web 应用程序中模拟物理相机? 在这篇博文中,我将向你展示如何使用 Three.js和 OpenCV 来完成此操作。 我们将从模拟针孔相机模型开始,然后添加真实的镜头畸变。 具体来说,我们将仔细研究 OpenCV 的两个失真模型,并使用后处理着色器复制它们。 拥有逼…

电子学会C/C++编程等级考试2022年06月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:倒序输出 依次输入4个整数a、b、c、d,将他们倒序输出,即依次输出d、c、b、a这4个数。 时间限制:1000 内存限制:65536输入 一行4个整数a、b、c、d,以空格分隔。 0 < a,b,c,d < 108输出 一行4个整数d、c、b、a,整数之…

Java自动化驱动浏览器搜索稻香

下载最新的Chrome浏览器 查看chrome版本&#xff0c;在浏览器地址栏输入&#xff1a;chrome://version/ 下载对应的浏览器驱动&#xff0c;将其放到一个目录中&#xff0c;我放到了D:/chromedriver-win64 导入对应的依赖【注意&#xff1a;不要导入最新的版本&#xff0c;最…

算法 LeetCode 题解 | 两个数组的交集

大家好&#xff0c;我是木川 一、题目描述 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 输出&#xff1a;[2] 示例…

C/C++最大质因子 2021年12月电子学会中小学生软件编程(C/C++)等级考试一级真题答案解析

目录 C/C最大质因子 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C最大质因子 一、题目要求 1、编程实现 质因子是指能整除给定正整数的质数。而最大质因子是指一个整数的所有质因子中最大的那个。…

【mediasoup】TransportCongestionControlClient 1: 代码走读

TransportCongestionControlClient 基于m77版本的libwebrtc ,但是TransportCongestionControlClient 并不是libwebrt中的,是mediasoup自己封装实现:TransportCongestionControlClient 用于发送端D:\XTRANS\soup\mediasoup-sfu-cpp\worker\src\RTC\TransportCongestionContro…

小黑子的SSM整合

SSM整合 一、基于restful页面数据交互1.1 后台接口开发1.2 页面访问处理 二、ssm整合2.1 流程分析2.2 整合配置2.3 功能模块开发2.4 接口测试2.5 表现层与前端数据传输协议定义2.5.1 协议实现 2.6 异常处理器2.6.1 RestControllerAdvice2.6.2 ExceptionHandler2.6.3 项目异常处…

DBeaver连接本地MySQL

原文&#xff1a; DBeaver21.3.0安装与连接本地MySQL_dbeaver创建本地数据库_傅大胖的博客-CSDN博客 其他&#xff1a; mysql 的驱动下载地址&#xff1a; Central Repository: mysql/mysql-connector-java ​​​​​​​

江湖再见,机器视觉兄弟们,我已经提离职了,聪明的机器视觉工程师,离职不亏本!

我闻江湖已叹息&#xff0c;又闻人间繁闹闹。同为布衣沦落人&#xff0c;相逢何必曾相识。 此生谁料事事休&#xff0c;道不尽人情冷暖&#xff0c;聚散离合总平常&#xff0c;不似勇气少年时。 我估计今年公司年底是发不出工资了&#xff0c;因为订单续不上。年终奖更是没有&…

Element Plus框架快速上手详解(一)

Element Plus框架快速上手详解 1、Element Plus1.1、安装 2、Button3、Link链接4、Layout布局5、Container布局容器6、Radio单选框6.1、单选框组6.2、事件 7、Checkbox多选框7.1、多选框组7.2、事件 8、Input输入框组件8.1、事件8.2、方法 9、Select选择器9.1、基础多选9.2、事…

机器学习二元分类 二元交叉熵 二元分类例子

二元交叉熵损失函数 深度学习中的二元分类损失函数通常采用二元交叉熵&#xff08;Binary Cross-Entropy&#xff09;作为损失函数。 二元交叉熵损失函数的基本公式是&#xff1a; L(y, y_pred) -y * log(y_pred) - (1 - y) * log(1 - y_pred)其中&#xff0c;y是真实标签&…

HarmonyOS开发(四):UIAbility组件

1、UIAbility概述 UIAbility 一种包含用户界面的应用组件用于与用户进行交互系统调度的单元为应用提供窗口在其中绘制界同 注&#xff1a;每一个UIAbility实例&#xff0c;都对应一个最近任务列表中的任务。 一个应用可以有一个UIAbility也可以有多个UIAbility。 如一般的…

【算法】二分查找-20231121

这里写目录标题 一、344. 反转字符串二、392. 判断子序列三、581. 最短无序连续子数组四、680. 验证回文串 II 一、344. 反转字符串 提示 简单 865 相关企业 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组…

(动手学习深度学习)第13章 实战kaggle竞赛:CIFAR-10

导入相关库 import collections import math import os import shutil import pandas as pd import torch import torchvision from torch import nn from d2l import torch as d2l下载数据集 d2l.DATA_HUB[cifar10_tiny] (d2l.DATA_URL kaggle_cifar10_tiny.zip,2068874e4…

内存学习(4):内存分类与常用概念3(ROM)

1 ROM介绍 ROM即为只读存储器&#xff0c;全拼是Read Only Memory。 1.1 “只读”的由来 ROM叫只读存储器是因为最早的ROM&#xff08;MROM&#xff09;确实是只能读取不能写入&#xff0c;一旦出厂不能再写&#xff0c;需要在出厂之前预设好它的数据&#xff0c;并且它是掉…

华为---OSPF网络虚连接(Virtual Link)简介及示例配置

OSPF网络虚连接&#xff08;Virtual Link&#xff09;简介 为了避免区域间的环路&#xff0c;OSPF规定不允许直接在两个非骨干区域之间发布路由信息&#xff0c;只允许在一个区域内部或者在骨干区域和非骨干区域之间发布路由信息。因此&#xff0c;每个ABR都必须连接到骨干区域…

Fourier分析导论——第6章——R^d 上的Fourier变换(E.M. Stein R. Shakarchi)

第6章 上的 Fourier 变换 It occurred to me that in order to improve treatment planning one had to know the distribution of the at- tenuation coefficient of tissues in the body. This in- formation would be useful for diagnostic purposes and would con…

[github配置] 远程访问仓库以及问题解决

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于新西兰奥克兰大学攻读IT硕士学位。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。跨领域…