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

react【五】redux/reduxToolkit/手写connext

文章目录

  • 1、回顾纯函数
  • 2、redux
    • 2.1 redux的基本使用
    • 2.2 通过action修改store的数值
    • 2.3 订阅state的变化
    • 2.4 目录结构
    • 2.5 Redux的使用过程
    • 2.6 redux的三大原则
    • 2.7 Redux官方图
  • 3、redux在React中的使用
  • 4、react-redux使用
    • 4.1 react-redux的基本使用
    • 4.2 异步请求 redux-thunk
    • 4.3 对redux代码结构进行优化 和 redux-devtools
  • 5、ReduxToolkit
    • 5.1 基本使用
    • 5.2 异步操作 写法1
    • 5.3 异步操作 写法2
  • 6、手写connext
  • 7、合并中间件
  • 8、React中的state如何管理

1、回顾纯函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、redux

2.1 redux的基本使用

  • pm install redux --save
  • 在这里插入图片描述
  • store
const { createStore } = require("redux");// 1.state数据
const initialState = {name: "kiki",age: "18",
};// 2.reducer纯函数
function reducer() {return initialState;
}// 3.创建store
const store = createStore(reducer);module.exports = store;

在这里插入图片描述

2.2 通过action修改store的数值

在这里插入图片描述

const { createStore } = require("redux");
const { ADD_NUMBER, CHANGE_NAME } = require("./constants");// 1.state数据
const initialState = {name: "kiki",num: 18,
};// 2.reducer纯函数// 两个参数
// 参数1:store目前保存的state 设置默认参数
// 参数2:本次需要更新的action
// 返回值 他的返回值作为之后存储在store的数值 因为第一次调用没有数值 所以设置默认值
function reducer(state = initialState, action) {console.log(state, action); // { name: 'kiki', num: '18' } { type: '@@redux/INIT0.n.r.y.w.j' }switch (action.type) {case ADD_NUMBER:// 这里需要创建新的对象的返回 否则页面发现state没有发生变化不会更新界面return { ...state, num: state.num + action.num };case CHANGE_NAME:return { ...state, name: action.name };default:return state;}
}// 3.创建store
const store = createStore(reducer);module.exports = store;

在这里插入图片描述

2.3 订阅state的变化

在这里插入图片描述

2.4 目录结构

在这里插入图片描述
在这里插入图片描述

2.5 Redux的使用过程

在这里插入图片描述

2.6 redux的三大原则

在这里插入图片描述

2.7 Redux官方图

在这里插入图片描述

3、redux在React中的使用

在这里插入图片描述

4、react-redux使用

yarn add react-redux

4.1 react-redux的基本使用

在这里插入图片描述

在这里插入图片描述

import React, { PureComponent } from "react";
import { connect } from "react-redux";
// import store from "../store"
import { addNumberAction, subNumberAction } from "../store/actionCreators";export class About extends PureComponent {calcNumber(num, isAdd) {if (isAdd) {console.log("加", num);this.props.addNumber(num);} else {console.log("减", num);this.props.subNumber(num);}}render() {const { counter, banners, recommends } = this.props;return (<div><h2>About Page: {counter}</h2><div><button onClick={(e) => this.calcNumber(6, true)}>+6</button><button onClick={(e) => this.calcNumber(88, true)}>+88</button><button onClick={(e) => this.calcNumber(6, false)}>-6</button><button onClick={(e) => this.calcNumber(88, false)}>-88</button></div></div>);}
}// connect()返回值是一个高阶组件
// function mapStateToProps(state) {
//   return {
//     counter: state.counter
//   }
// }// function fn2(dispatch) {
//   return {
//     addNumber(num) {
//       dispatch(addNumberAction(num))
//     },
//     subNumber(num) {
//       dispatch(subNumberAction(num))
//     }
//   }
// }const mapStateToProps = (state) => ({counter: state.counter,banners: state.banners,recommends: state.recommends,
});const mapDispatchToProps = (dispatch) => ({addNumber(num) {dispatch(addNumberAction(num));},subNumber(num) {dispatch(subNumberAction(num));},
});// connect是高阶组件
export default connect(mapStateToProps, mapDispatchToProps)(About);

4.2 异步请求 redux-thunk

yarn add redux-thunk
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.3 对redux代码结构进行优化 和 redux-devtools

每个页面可能都会有自己的store为了方便维护,将store按照页面划分
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

import { createStore, applyMiddleware, compose, combineReducers } from "redux";
import thunk from "redux-thunk";import counterReducer from "./counter";
import homeReducer from "./home";
import userReducer from "./user";// 正常情况下 store.dispatch(object)
// 想要派发函数 store.dispatch(function)// 将两个reducer合并在一起
const reducer = combineReducers({counter: counterReducer,home: homeReducer,user: userReducer,
});// combineReducers实现原理(了解)
// function reducer(state = {}, action) {
//   // 返回一个对象, store的state
//   return {
//     counter: counterReducer(state.counter, action),
//     home: homeReducer(state.home, action),
//     user: userReducer(state.user, action)
//   }
// }// redux-devtools
// trace的功能是可以追踪源码
const composeEnhancers =window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true }) || compose;// thunk 是用来发送异步请求的增强写法
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));export default store;

在这里插入图片描述

在这里插入图片描述

5、ReduxToolkit

5.1 基本使用

npm install @reduxjs/toolkit react-redux
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 需要在根组件传递store的值
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
import React, { PureComponent } from "react";
import { connect } from "react-redux";
import { changeNumber } from "../store/features/counter";export class About extends PureComponent {changeNum(num) {this.props.changeNumber(num);}render() {const { counter } = this.props;return (<div>{counter}<button onClick={(e) => this.changeNum(5)}>+5</button></div>);}
}const mapStateToProps = (state) => ({counter: state.counter.counter,
});const mapDispatchToProps = (dispatch) => ({changeNumber(num) {dispatch(changeNumber(num));},
});export default connect(mapStateToProps, mapDispatchToProps)(About);

5.2 异步操作 写法1

在这里插入图片描述

import { createAsyncThunk } from "@reduxjs/toolkit";
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";// toolkit已经集成了thunk所以可以直接使用
// 第一个参数是name可以根据自己的喜好取
// 可以把这个函数看成是promise 它跟promise十分相似
export const fetchHomeMultidataAction = createAsyncThunk("fetch/homemultidata",// dispatch传递的参数是第一个 extraInfoasync (extraInfo, { dispatch, getState }) => {console.log(extraInfo);const res = await axios.get("http://123.207.32.32:8000/home/multidata");// 不能直接返回res 没办法直接对其进行序列化return res.data;}
);const homeSlice = createSlice({name: "home",initialState: {banner: [],},reducers: {changeBanner(state, { payload }) {state.banner = payload;},},// 这里是对异步操作进行操作的方法extraReducers: {[fetchHomeMultidataAction.pending](state, action) {console.log(action);},[fetchHomeMultidataAction.fulfilled](state, { payload, meta }) {// 异步操作返回的参数state.banner = payload.data.banner.list;// 在dispatch时传递的参数console.log(meta.arg);},[fetchHomeMultidataAction.rejected](state, action) {console.log("fetchHomeMultidataAction rejected");},},
});export const { changeBanner } = homeSlice.actions;
export default homeSlice.reducer;

在这里插入图片描述

5.3 异步操作 写法2

在这里插入图片描述

import { createAsyncThunk } from "@reduxjs/toolkit";
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";// toolkit已经集成了thunk所以可以直接使用
// 第一个参数是name可以根据自己的喜好取
// 可以把这个函数看成是promise 它跟promise十分相似
export const fetchHomeMultidataAction = createAsyncThunk("fetch/homemultidata",// dispatch传递的参数是第一个 extraInfoasync (extraInfo, { dispatch, getState }) => {console.log(extraInfo);const res = await axios.get("http://123.207.32.32:8000/home/multidata");// 不能直接返回res 没办法直接对其进行序列化return res.data;}
);const homeSlice = createSlice({name: "home",initialState: {banner: [],},reducers: {changeBanner(state, { payload }) {state.banner = payload;},},// 这里是对异步操作进行操作的方法// extraReducers: {//   [fetchHomeMultidataAction.pending](state, action) {//     console.log(action);//   },//   [fetchHomeMultidataAction.fulfilled](state, { payload, meta }) {//     // 异步操作返回的参数//     state.banner = payload.data.banner.list;//     // 在dispatch时传递的参数//     console.log(meta.arg);//   },//   [fetchHomeMultidataAction.rejected](state, action) {//     console.log("fetchHomeMultidataAction rejected");//   },// },extraReducers: (builder) => {builder.addCase(fetchHomeMultidataAction.pending, (state, action) => {console.log("fetchHomeMultidataAction pending");}).addCase(fetchHomeMultidataAction.fulfilled, (state, { payload }) => {state.banners = payload.data.banner.list;state.recommends = payload.data.recommend.list;});},
});export const { changeBanner } = homeSlice.actions;
export default homeSlice.reducer;

6、手写connext

// connect的参数:
// 参数一: 函数
// 参数二: 函数
// 返回值: 函数 => 高阶组件import { PureComponent } from "react";
import { StoreContext } from "./StoreContext";
// import store from "../store"//  实际上就是一个高阶函数里面嵌套一个高阶组件
export function connect(mapStateToProps, mapDispatchToProps, store) {// 高阶组件: 函数return function (WrapperComponent) {class NewComponent extends PureComponent {//  接收的第二个参数就是contextconstructor(props, context) {super(props);this.state = mapStateToProps(context.getState());}componentDidMount() {// 因为页面发生改变是connect自己内部实现的 我们自己手写的话 要手动调用this.unsubscribe = this.context.subscribe(() => {// 不能直接通过强制刷新 不然性能很低// this.forceUpdate()// 执行ToProps的方法 自己判断是否state发生了变化this.setState(mapStateToProps(this.context.getState()));});}componentWillUnmount() {this.unsubscribe();}render() {// 传递进来的两个方法进行调用 再把他们的数值传递给组件 实现了高阶组件的增强const stateObj = mapStateToProps(this.context.getState());const dispatchObj = mapDispatchToProps(this.context.dispatch);return (<WrapperComponent {...this.props} {...stateObj} {...dispatchObj} />);}}// 为了避免每次store都是需要传入进来 所以创建了一个context 在注册应用的时候就将他导入NewComponent.contextType = StoreContext;return NewComponent;};
}

在这里插入图片描述
在这里插入图片描述

7、合并中间件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8、React中的state如何管理

在这里插入图片描述

相关文章:

react【五】redux/reduxToolkit/手写connext

文章目录 1、回顾纯函数2、redux2.1 redux的基本使用2.2 通过action修改store的数值2.3 订阅state的变化2.4 目录结构2.5 Redux的使用过程2.6 redux的三大原则2.7 Redux官方图 3、redux在React中的使用4、react-redux使用4.1 react-redux的基本使用4.2 异步请求 redux-thunk4.3…...

.NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2

前言 很多同学都不愿给电脑设动态壁纸&#xff0c;其中有个重要原因就是嫌它占资源过多。今天大姚分享一个.NET开源、免费&#xff08;MIT license&#xff09;的一个小而快并且功能强大的 Windows 动态桌面软件&#xff0c;支持视频和网页动画播放&#xff1a;DreamScene2。 …...

jsp计算机线上教学系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 计算机线上教学系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5…...

RabbitMQ的高可用机制

RabbitMQ通过多种机制提供高可用性(HA)支持&#xff0c;以确保消息系统的稳定性和可靠性。下面将详细介绍这些机制&#xff0c;并提供代码示例。 集群&#xff08;Clustering&#xff09; RabbitMQ的集群提供了高可用性和负载均衡。集群中的节点共享同一个Erlang分布式数据库…...

人机协同中的贝叶斯和马尔可夫

人机协同中的马尔可夫链是指在人与机器之间协同工作过程中&#xff0c;可能涉及到的状态转移概率模型。马尔可夫链是一种数学模型&#xff0c;描述了在给定当前状态下&#xff0c;未来状态的概率分布只依赖于当前状态&#xff0c;而与过去状态无关的随机过程。在人机协同工作中…...

STM32的SDIO

一.SDIO简介 SDIO&#xff0c;全称Secure Digital Input/Output&#xff0c;是一种用于在移动设备和嵌入式系统中实现输入/输出功能的接口标准。它结合了SD卡的存储功能和I/O功能&#xff0c;允许设备通过SD卡槽进行数据输入输出和外围设备连接。 SDIO接口通常被用于连接各种…...

Unity中的Lerp插值的使用

Unity中的Lerp插值使用 前言Lerp是什么如何使用Lerp 前言 平时在做项目中插值的使用避免不了&#xff0c;之前一直在插值中使用存在误区&#xff0c;在这里浅浅记录一下。之前看的博客或者教程还多都存在一个“永远到达不了&#xff0c;只能无限接近”的一个概念。可能是之前脑…...

年后上来面了一个来字节要求月薪23K,明显感觉他背了很多面试题...

最近有朋友去字节面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…...

代码随想录算法训练营DAY20 | 二叉树 (8)

一、LeetCode 701 二叉搜索树中的插入操作 题目链接&#xff1a; 701.二叉搜索树中的插入操作https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/ 思路&#xff1a;见缝插针罢辽。 class Solution {public TreeNode insertIntoBST(TreeNode root, i…...

2023年全球软件开发大会(QCon北京站2023)2月:核心内容与学习收获(附大会核心PPT下载)

本次峰会是一个汇集了最新技术趋势、最佳实践和创新思维的盛会。对于从事软件开发和相关领域的专业人士来说&#xff0c;参加这样的大会将有助于他们了解行业动态、提升技能水平、拓展职业视野&#xff0c;并与同行建立联系和合作。 本次峰会包含&#xff1a;AI基础架构、DevO…...

键盘输入4个数,从小到大排序

题目 键盘输入4个整数&#xff0c;从小到大排序 思路 代码 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//键盘输入4个整数&#xff0c;从小到大排序 int main() {int n1, n2, n3, n4;scanf_s("%d %d %d %d", &n1, &n2, &n3, &n4);…...

Day11-Linux系统iNode及链接知识及企业按哪里精讲

Day11-Linux系统iNode及链接知识及企业按哪里精讲 1. 文件核心 属性知识1.1 什么是索引节点&#xff08;inode&#xff09;。1.2 索引节点作用1.3 inode是怎么产生的&#xff1f;1.4 inode的特点&#xff1f;1.5 Linux系统读取文件的原理1.6 企业生产案例&#xff1a;No space …...

C# Thread的使用

在C#中&#xff0c;线程用于实现程序的并发执行。通过创建和管理多个线程&#xff0c;可以同时处理不同的任务或操作&#xff0c;从而提高程序性能和响应性。以下是如何在C#中使用线程的基本步骤&#xff1a; 创建新线程 // 使用System.Threading命名空间 using System.Threa…...

ETL数据集成工具DataX、Kettle、ETLCloud特点对比

ETL数据集成工具 对于数据仓库&#xff0c;大数据集成类应用&#xff0c;通常会采用ETL工具辅助完成。ETL&#xff0c;是英文 Extract-Transform-Load 的缩写&#xff0c;用来描述将数据从来源端经过抽取(extract) 、交互转换(transform) 、加载(load)至的端的过程当前的很多应…...

OpenAI:Sora视频生成模型技术报告(中文)

概述 视频生成模型作为世界模拟器 我们探索视频数据生成模型的大规模训练。具体来说&#xff0c;我们在可变持续时间、分辨率和宽高比的视频和图像上联合训练文本条件扩散模型。我们利用transformer架构&#xff0c;在视频和图像潜在代码的时空补丁上运行。我们最大的模型Sor…...

Java基于微信小程序的乐室预约小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

Linux常见指令(一)

目录 一、基本指令 1.1ls指令 1.2pwd指令 1.3cd指令 1.4touch指令 1.5mkdir指令 1.6rmdir指令、rm指令 1.7man指令 1.8cp指令 1.9mv指令 1.10cat 一、基本指令 1.1ls指令 语法 &#xff1a; ls [ 选项 ][ 目录或文件 ] 功能&#xff1a;对于目录&#xff0c;该命令…...

大端和小端传输字节完整版

大端和小端传输字节序 大端和小端一、最高有效位、最低有效位1.MSB(Most significant Bit)最高有效位2.LSB(Least Significant Bit)最低有效位 二、内存地址三、大端和小端四、网络字节序和主机字节序五、C#位操作符六、C#中关于大端和小端的转换七、关于负数八、关于汉字编码以…...

华为23年9月笔试原题,巨详细题解,附有LeetCode测试链接

文章目录 前言思路主要思路关于f函数的剖析Code就到这&#xff0c;铁子们下期见&#xff01;&#xff01;&#xff01;&#xff01; 前言 铁子们好啊&#xff01;今天阿辉又给大家来更新新一道好题&#xff0c;下面链接是23年9月27的华为笔试原题&#xff0c;LeetCode上面的ha…...

ES实战--性能提升

触发冲刷的条件: 1.内存缓冲区已满 2.自上次冲刷后超过了一定时间 3.事务日志达到了一定阀值 对名为get-together的Elasticsearch索引执行优化操作&#xff0c;将索引中的数据段&#xff08;segments&#xff09;合并到指定的数量1 GET /get-together/_optimize?max_num_segm…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...