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如何管理

在这里插入图片描述

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

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

相关文章

课时26:内容格式化_常用符号解读_终端输出

3.1.2 终端输出 学习目标 这一节&#xff0c;我们从 后台执行、信息符号、小结 三个方面来学习。 后台执行 简介 & 就是将一个命令从前台转到后台执行,使用格式如下&#xff1a;命令 &简单演示 前台执行休眠命令 [rootlocalhost ~]# sleep 4 界面卡住4秒后消失后…

字符串大小比较的方法以及函数的多返回值

1.字符串的大小比较: 按照ASCII码表的值进行比较字符串大小 print(f"abc大于abd,结果为{abc>abd}") #结果为布尔类型False print(f"a大于A,结果为{a>A}") #True print(f"key1大于key2,结果为{key1>key2}") #False 2.函数的多返回值: …

分布式文件系统 SpringBoot+FastDFS+Vue.js

分布式文件系统 SpringBootFastDFSVue.js 一、分布式文件系统1.1.文件系统1.2.什么是分布式文件系统1.3.分布式文件系统的出现1.3.主流的分布式文件系统1.4.分布式文件服务提供商1.4.1.阿里OSS1.4.2.七牛云存储1.4.3.百度云存储 二、fastDFS2.1.fastDSF介绍2.2.为什么要使用fas…

<s-table>、<a-table>接收后端数据

对于 中的 <template #bodyCell“{ column, record }”> &#xff1a; <s-tableref"table":columns"columns":data"loadData":alert"options.alert.show"bordered:row-key"(record) > record.id":tool-config&…

MacOS - M1芯片 Mac 在“恢复”模式中启用系统扩展教程

部分软件需要开启系统扩展才能正常使用&#xff0c;但是默然M1芯片的Mac不能直接打开系统扩展&#xff0c;如下两图。 若要启用系统扩展&#xff0c;您需要在“恢复”环境中修改安全性设置。 若要执行此操作&#xff0c;请将系统关机&#xff0c;然后按住触控ID或电源按钮以开…

MATLAB 1:基础知识

MATLAB中的数据类型主要包括数值类型、逻辑类型、字符串、函数句柄、结构体和单元数组类型。这六种基本的数据类型都是按照数组形式存储和操作的。 MATLAB中还有两种用于高级交叉编程的数据类型&#xff0c;分别是用户自定义的面向对象的用户类类型和Java类类型。 1.1.1数值类…

Stable Diffusion 模型下载:majicMIX reverie 麦橘梦幻

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

二级 C 语言笔试-12

一、选择题 1. 软件是指 A) 程序 B) 程序和文档 C) 算法加数据结构 D) 程序、数据与相关文档的完整集合 2. 下面不属于软件设计原则的是 A) 抽象 B) 模块化 C) 白底向上 D) 信息隐蔽 3. 树是结点的集合&#xff0c;它的根结点的数目是( )。 A) 有且只有 1 个 B) 1 或多于 1 C) …

洛谷: P9749 [CSP-J 2023] 公路

思路: 贪心思想指的是在对问题求解的时候&#xff0c;总是能做出在当前看来是最好的选择,也就是说&#xff0c;如果要得到整个问题的最优答案&#xff0c;那么要求每一步都能做出最好的选择&#xff08;feihua&#xff09;。 在这道题里面&#xff0c;我们希望在来到第i站的时…

Windows搭建docker+k8s

安装Docker Desktop 从官网下载&#xff0c;然后直接安装即可&#xff0c;过程很简单&#xff0c;一直Next就行。 有一点需要注意就是要看好对应的版本&#xff0c;因为后边涉及到版本的问题。 https://www.docker.com/products/docker-desktop 安装完成&#xff0c;双击图…

Python列表clear()方法详解与实例

Python列表clear()方法详解与实例 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;clear()&#x1f333;&#x1f340;功能介绍&#x1f340;&#x1f340;语法&#x1f340;&#x1f340;示例&#x1f340;&#x1f340;注意事项&#x1f34…

go面试题--使用两个goroutine交替打印数字与字母

使用两个goroutine交替打印数字与字母 题目如下&#xff1a; 使用两个goroutine交替打印序列&#xff0c;一个goroutine打印数字&#xff0c;另外一个goroutine打印字母&#xff0c;最终效果如下&#xff1a; 12AB34CD56EF78GH910IZ1112KL1314MN1516OP1718QR1920ST2122UV2324W…

【白话前端】快速区分webGL,webGPU,unity3D和UE4

在3D图形渲染的渲染领域&#xff0c;很多友友们对上述概念傻傻分不清&#xff0c;站在前端开发角度&#xff0c;我用简单语言说下&#xff0c;结论在文章最后。 一、四者都能进行3D图形渲染 它们之间有一些区别&#xff0c;下面我将对它们进行简单的区分&#xff1a; WebGPU&a…

探索设计模式的魅力:捕捉变化的风-用观察者模式提升用户体验

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 一、引言 核心概念 应用场景 可以解决的问题 二、场景案例 2.1 不用设计模式实现 2.2 存在问题 2.3 使用设计模式实现 2.4 成功克服 三、工作原理 3.1 结构图和说明 3.2 工作原理详解 3.3 实现步骤 四、 优…

TCP 和 UDP的区别

文章目录 概述区别UDPTCPTCP与UDP的选择UDP和TCP编程区别 概述 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;和 UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是互联网中两种最常用的传输层协议 总的来…

C++笔记:容器适配器:优先级队列(priority_queue)模拟实现

文章目录 框架(constructor)size()、empty()、top()push()声明参数实现代码 pop()声明实现代码 仿函数与函数指针仿函数的定义仿函数实现回调函数指针实现回调adjust_up 和 adjust_down 的改进 完整代码 容器适配器&#xff08;Container Adapter&#xff09;是一种 C 中的抽象…

【每日一题】牛客网——链表的回文结构

✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢迎各位大佬指点&#xff0c;相互学习…

Leetcode 718 最长重复子数组

题意理解&#xff1a; 给两个整数数组 nums1 和 nums2 &#xff0c;返回 两个数组中 公共的 、长度最长的子数组的长度 。 如&#xff1a; nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 则最长重复子序列为&#xff1a; 321 长度为3 这里采用动态规划解决这个问题。最长公共子序…

centos7更新yum安装docker-ce使用阿里源

centos7更新yum安装docker-ce使用阿里源 centos7更新yum安装docker-ce使用阿里源240209版 #!/bin/bash ## 卸载之前的docke sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \dock…

OpenCV-38 图像金字塔

目录 一、图像金字塔 1. 高斯金字塔 2. 拉普拉斯金字塔 一、图像金字塔 图像金字塔是图像中多尺度表达的一种&#xff0c;最主要用于图像的分割&#xff0c;是一种以多分辨率来解释图像的有效但概念简单的结构。简单来说&#xff0c;图像金字塔是同一图像不同分辨率的子图…