React整理总结(五、Redux)

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) => {
// 第一个canconst 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.mzph.cn/news/152785.shtml

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

相关文章

猫12分类:使用yolov5训练检测模型

前言&#xff1a; 在使用yolov5之前&#xff0c;尝试过到百度飞桨平台&#xff08;小白不建议&#xff09;、AutoDL平台&#xff08;这个比较友好&#xff0c;经济实惠&#xff09;训练模型。但还是没有本地训练模型来的舒服。因此远程了一台学校电脑来搭建自己的检测模型。配置…

hdfsClient_java对hdfs进行上传、下载、删除、移动、打印文件信息尚硅谷大海哥

Java可以通过Hadoop提供的HDFS Java API来控制HDFS。通过HDFS Java API&#xff0c;可以实现对HDFS的文件操作&#xff0c;包括文件的创建、读取、写入、删除等操作。 具体来说&#xff0c;Java可以通过HDFS Java API来创建一个HDFS文件系统对象&#xff0c;然后使用该对象来进…

集合的自反关系和对称关系

集合的自反关系和对称关系 一&#xff1a;集合的自反关系1&#xff1a;原理&#xff1a;2&#xff1a;代码实现 二&#xff1a;对称关系1&#xff1a;原理&#xff1a;2&#xff1a;代码实现 三&#xff1a;总结 一&#xff1a;集合的自反关系 1&#xff1a;原理&#xff1a; …

【python】直方图正则化详解和示例

直方图正则化&#xff08;Histogram Normalization&#xff09;是一种图像增强技术&#xff0c;目的是改变图像的直方图以改善图像的质量。具体来说&#xff0c;它通过将图像的直方图调整为指定的形状&#xff0c;以增强图像的对比度和亮度。 直方图正则化的基本步骤如下&…

【Android Jetpack】Hilt的理解与浅析

文章目录 依赖注入DaggerHiltKoin添加依赖项Hilt常用注解的含义HiltAndroidAppAndroidEntryPointInjectModuleInstallInProvidesEntryPoint Hilt组件生命周期和作用域如何使用 Hilt 进行依赖注入 本文只是进行了简单入门&#xff0c;博客仅当做笔记用。 依赖注入 依赖注入是一…

某60区块链安全之不安全的随机数实战二学习记录

区块链安全 文章目录 区块链安全不安全的随机数实战二实验目的实验环境实验工具实验原理实验内容EXP利用 不安全的随机数实战二 实验目的 学会使用python3的web3模块 学会以太坊不安全的随机数漏洞分析及利用 实验环境 Ubuntu18.04操作机 实验工具 python3 实验原理 由…

吴恩达《机器学习》9-1:代价函数

一、引入新标记方法 首先&#xff0c;引入一些新的标记方法&#xff0c;以便更好地讨论神经网络的代价函数。考虑神经网络的训练样本&#xff0c;其中每个样本包含输入 x 和输出信号 y。我们用 L 表示神经网络的层数&#xff0c;表示每层的神经元个数&#xff08;表示输出层神…

基于单片机GPS轨迹定位和里程统计系统

**单片机设计介绍&#xff0c; 基于单片机GPS轨迹定位和里程统计系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 一个基于单片机、GPS和里程计的轨迹定位和里程统计系统可以被设计成能够在移动的交通工具中精确定位车辆的位置…

Spring Boot - 自定义注解来记录访问路径以及访问信息,并将记录存储到MySQL

1、准备阶段 application.properties&#xff1b;yml 可通过yaml<互转>properties spring.datasource.urljdbc:mysql://localhost:3306/study_annotate spring.datasource.usernameroot spring.datasource.password123321 spring.datasource.driver-class-namecom.mysq…

【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…

苹果CMS首涂第30套可装修DIY主题模板免授权版

这是一款可以装修的主题&#xff0c;类似淘宝店装修一样&#xff0c;可以针对首页、栏目页、详情页、播放页进行自定义装修&#xff0c;内置10个模块自由选择、添加、修改、删除、排序操作&#xff0c;后续升级还会增加更多实用和个性模块供选择&#xff0c;主题内包含的导航、…

Actor对象的引用 怎么设置他的材质?或设置是否启用重力?

这个蓝图我是想当重叠触发,将另一个Target Actor(一个球体)设置他的z增加50,但是为什么在触发的时候会抽搐?而且我想要设置他的材质等等这些属性都不行

什么是希尔伯特空间?

照片由 丹克里斯蒂安佩杜雷什 on Unsplash 一、说明 在本文中&#xff0c;我们将探讨希尔伯特空间这个非常重要的主题。希尔伯特空间由于其特性而经常出现在物理和工程中。为了理解希尔伯特空间&#xff0c;我们从度量空间的定义开始。 二、基础概念 集合是定义明确的元素的集合…

Flutter 使用 device_info_plus 遇到的问题

问题&#xff1a;引用device_info_plus 插件出现了异常&#xff0c;不知道为啥打开项目的时候就不能用了。 解决&#xff1a;改了版本解决 Target of URI doesnt exist: package:device_info_plus/device_info_plus.dart. (Documentation) Try creating the file reference…

广州华锐互动VRAR | VR课件内容编辑器解决院校实践教学难题

VR课件内容编辑器由VR制作公司广州华锐互动开发&#xff0c;是一款专为虚拟现实教育领域设计的应用&#xff0c;它能够将传统的教学内容转化为沉浸式的三维体验。通过这款软件&#xff0c;教师可以轻松创建和编辑各种虚拟场景、模型和动画&#xff0c;以更生动、直观的方式展示…

kafka本地安装报错

Error: VM option ‘UseG1GC’ is experimental and must be enabled via -XX:UnlockExperimentalVMOptions. #打开 bin/kafka-run-class.sh KAFKA_JVM_PERFORMANCE_OPTS“-server -XX:UseG1GC -XX:MaxGCPauseMillis20 -XX:InitiatingHeapOccupancyPercent35 -XX:ExplicitGCInv…

基于安卓android微信小程序的好物分享系统

运行环境 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&a…

ModernCSS.dev - 来自微软前端工程师的 CSS 高级教程,讲解如何用新的 CSS 语法来解决旧的问题

今天给大家安利一套现代 CSS 的教程&#xff0c;以前写网页的问题&#xff0c;现在都可以用新的写法来解决了。 ModernCSS.dev 是一个现代 CSS 语法的教程&#xff0c;讲解新的 CSS 语法如何解决一些传统问题&#xff0c;一共有30多课。 这套教程的作者是 Stephanie Eckles&am…

【开源】基于JAVA的校园二手交易系统

项目编号&#xff1a; S 009 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S009&#xff0c;文末获取源码。} 项目编号&#xff1a;S009&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手商品档案管理模…

汇编-loop循环指令

LOOP指令是根据ECX计数器循环&#xff0c;将语句块重复执行特定次数。 ECX自动作为计数器&#xff0c; 每重复循环一次就递减1。 语法如下所示&#xff1a; 循环目的地址必须在距离当前位置计数器的-128到127字节范围内 LOOP指令的执行有两个步骤&#xff1a; 第一步&…