前端学习--React(3)

一、Redux

集中状态管理工具,不需要react即可使用,每个store的数据都是独立于组件之外的

vue小链接:vuex/pinia

基本使用

Redux将数据修改流程分成三个概念,state、action和reducer

state - 一个对象 存放我们管理的数据状态

action - 一个对象 描述你如何修改数据

reducer - 一个函数 根据action的描述生成新的state

<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button><script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script><script>// 1. 定义reducer函数 // 作用: 根据不同的action对象,返回不同的新的state// state: 管理的数据初始状态// action: 对象 type 标记当前想要做什么样的修改function reducer (state = { count: 0 }, action) {// 数据不可变:基于原始状态生成一个新的状态 所以要返回新对象if (action.type === 'INCREMENT') {return { count: state.count + 1 }}if (action.type === 'DECREMENT') {return { count: state.count - 1 }}return state}// 2. 使用reducer函数生成store实例const store = Redux.createStore(reducer)// 3. 通过store实例的subscribe订阅数据变化// 回调函数可以在每次state发生变化的时候自动执行store.subscribe(() => {console.log('state变化了', store.getState())document.getElementById('count').innerText = store.getState().count})// 4. 通过store实例的dispatch函数提交action更改状态 const inBtn = document.getElementById('increment')inBtn.addEventListener('click', () => {// 增store.dispatch({type: 'INCREMENT'})})const dBtn = document.getElementById('decrement')dBtn.addEventListener('click', () => {// 减store.dispatch({type: 'DECREMENT'})})// 5. 通过store实例的getState方法获取最新状态更新到视图中</script>

react中使用redux

相关工具

Redux Toolkit 简化redux书写逻辑

react-redux 链接Redux和React的中间件

npm i @reduxjs/toolkit react-redux

 安装成功

目录创建

创建src/store,modules存放子模块

counterStore.js

//1 导入并创建store
import {createSlice} from "@reduxjs/toolkit"const counterStore = createSlice({name:'counter',// 初始状态initialState:{count:0},// 更新状态的方法reducers:{inscrement(state){state.count++},descrement(state){state.count --}}
})const {inscrement, descrement} = counterStore.actions
const reducer = counterStore.reducerexport{inscrement,descrement
}export default reducer

store/index.js

集成store/modules中所有子模块

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore"// 将子模块中的所有store合成一个根store方便访问
const store = configureStore({reducer:{counter:counterReducer,}
})export default store

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from "./store"
import { Provider } from 'react-redux';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(// 通过react-redux提供的Provider 给组件注入store 使得redux定义的store能够被react组件使用<Provider store={store}><App /></Provider>
);

App.js

useDispatch() 通过这个来派发reducer修改状态

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement} from "./store/modules/counterStore"
function App() {const { count } = useSelector(state => state.counter)const dispatch = useDispatch()return (<div className="App"><button onClick={() => dispatch(inscrement())}>+</button>{count}<button onClick={() => dispatch(descrement())}>-</button></div>);
}export default App;

然后就完成了:

进阶版-提交action时传参

counterStore.js

增加了一个addToNum函数

//1 导入并创建store
import {createSlice} from "@reduxjs/toolkit"const counterStore = createSlice({name:'counter',// 初始状态initialState:{count:0},// 更新状态的方法reducers:{inscrement(state){state.count++},descrement(state){state.count --},addToNum(state, action){// dispatch调用该方法时传入的参数就存放在action.payloadstate.count += action.payload}}
})const {inscrement, descrement, addToNum} = counterStore.actions
const reducer = counterStore.reducerexport{inscrement,descrement,addToNum
}export default reducer

 App.js

增加了两个值,传入不同参数

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement, addToNum} from "./store/modules/counterStore"
function App() {const { count } = useSelector(state => state.counter)const dispatch = useDispatch()return (<div className="App"><button onClick={() => dispatch(inscrement())}>+</button>{count}<button onClick={() => dispatch(descrement())}>-</button><button onClick={() => dispatch(addToNum(10))}>+ 10</button><button onClick={() => dispatch(addToNum(-10))}>- 10</button></div>);
}export default App;

再进阶版-异步状态操作

channelStore.js

import {createSlice} from '@reduxjs/toolkit'
import axios from 'axios'const channelStore = createSlice({name:'channel',initialState:{channelList:[]},reducers:{getChannels(state, action){state.channelList = action.payload}}
})const {getChannels} = channelStore.actions//单独写一个异步action的函数 异步操作处理完毕后再调用同步action修改状态
const getChannelList = () => {return async(dispatch) => {const res = await axios.get('http://geek.itheima.net/v1_0/channels')dispatch(getChannels(res.data.data.channels))}
}export {getChannelList}const reducer = channelStore.reducer
export default reducer

 App.js

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement, addToNum} from "./store/modules/counterStore"
import {getChannelList} from "./store/modules/channelStore"
import {useEffect} from 'react'
function App() {const { count } = useSelector(state => state.counter)const { channelList } = useSelector(state => state.channel)const dispatch = useDispatch()useEffect(()=> {dispatch(getChannelList())}, [dispatch])return (<div className="App"><button onClick={() => dispatch(inscrement())}>+</button>{count}<button onClick={() => dispatch(descrement())}>-</button><button onClick={() => dispatch(addToNum(10))}>+ 10</button><button onClick={() => dispatch(addToNum(-10))}>- 10</button><ul>{channelList.map(item => <li key={item.id}>{item.name}</li>)}</ul></div>);
}export default App;

调试工具redux devtools

直接在chorme商店里下载

 

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

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

相关文章

某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】

文章目录 前言js实现push方法js实现订阅发布手写防抖节流手写reduce方法深拷贝es5去重数组多维数组去重排序简单递归实现树形结构输出遍历后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端面试 &#x1f431;‍&#x1f453;博主在前…

Linux僵死进程及文件操作

1.僵死进程(僵尸进程)&#xff1a; 1.僵死进程产生的原因或者条件: 什么是僵死进程? 当子进程先于父进程结束,父进程没有获取子进程的退出码,此时子进程变成僵死进程. 简而言之,就是子进程先结束,并且父进程没有获取它的退出码; 那么僵死进程产生的原因或者条件就是:子进…

直接插入排序和希尔排序

前言 我们前面几期介绍了线性和非线性的基本数据结构。例如顺序表、链表、栈和队列、二叉树等~&#xff01;本期和接下来的几期我们来详解介绍各个排序的概念、实现以及性能分析&#xff01; 本期内容 排序的概念以及其运用 常见的排序算法 直接插入排序 希尔排序 一、排序的…

vue2项目从0搭建(三):配置环境变量及对应的webpack配置

前言 实际业务开发中,一个项目很可能会同时配置好几套环境。 比如:常规开发环境,开发测试环境,正式的测试环境,预发测试环境,客户甲的生产环境,客户乙的生产环境,通用生产环境,独立应用环境,微前端环境,大屏专用环境,移动端环境。 一女多嫁的实际业务场景,就需要我们进行多样…

安卓用SQLite数据库存储数据

什么是SQLite&#xff1f; SQLite是安卓中的轻量级内置数据库&#xff0c;不需要设置用户名和密码就可以使用。资源占用较少&#xff0c;运算速度也比较快。 SQLite支持&#xff1a;null&#xff08;空&#xff09;、integer&#xff08;整形&#xff09;、real&#xff08;小…

第29期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

Linux篇:文件系统

一、共识原理&#xff1a; 文件文件内容文件属性 磁盘上存储文件存文件的内容&#xff08;数据块&#xff09;存文件的属性&#xff08;inode&#xff09; Linux的文件在磁盘中存储是将属性和内容分开存储的。 二、硬件简述&#xff1a; 1. 认识硬件 磁盘&#xff1a;唯一的一…

混合云案例:利用 Databend Cloud 高效加速私有 Databend 的策略与实施

背景 Databend 是一款基于对象存储的存算分离湖仓产品&#xff0c;已成为云上大数据分析中高效且低成本的首选解决方案。目前&#xff0c;Databend 在多个用户场景中得到广泛应用&#xff0c;包括&#xff1a; 新媒体行业数据分析及大屏数据展示云上 CDH 替代以减少本地磁盘和…

Deep Image Prior

深度图像先验 论文链接&#xff1a;https://sites.skoltech.ru/app/data/uploads/sites/25/2018/04/deep_image_prior.pdf 项目链接&#xff1a;https://github.com/DmitryUlyanov/deep-image-prior Abstract 深度卷积网络已经成为一种流行的图像生成和恢复工具。一般来说&a…

web:[ZJCTF 2019]NiZhuanSiWei1

题目 点进题目&#xff0c;网页显示如下&#xff0c;需要代码审计 $_GET["text"]和$_GET["file"]来获取传入的两个参数text和file。使用isset()函数来检查$text变量是否已设置并且不为null。如果设置了并且不为null&#xff0c;则执行下面的逻辑。在下面的…

汽车电子 -- 车载ADAS之LCA(变道辅助系统)

相关法规文件: LCA: ISO 17387-2008 Intelligent transport systems — Lane change decision aid systems 一、变道辅助系统 LCA &#xff08;Lane Change Assist&#xff09; LCA 系统&#xff08;变道辅助系统&#xff09;监测后方相邻车道区域&#xff0c;如果有车辆在后…

《融合SCADA系统数据的天然气管道泄漏多源感知技术研究》误报数据识别模型开发

数据处理不作表述。因为我用的是处理后的数据&#xff0c;数据点这。 文章目录 工作内容1CC040VFD电流VFD转速压缩机转速反馈进出口差压 紧急截断阀开到位进出电动阀开到位发球筒电筒阀开到位收球筒电动阀开到位电动阀2005开到位越站阀开到位 工作内容2工作内容3 工作内容1 任…

Java小游戏 王者荣耀

GameFrame类 所需图片&#xff1a; package 王者荣耀;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayLis…

<JavaDS> 二叉树遍历各种遍历方式的代码实现 -- 前序、中序、后序、层序遍历

目录 有以下二叉树&#xff1a; 一、递归 1.1 前序遍历-递归 1.2 中序遍历-递归 1.3 后序遍历-递归 二、递归--使用链表 2.1 前序遍历-递归-返回链表 2.2 中序遍历-递归-返回链表 2.3 后序遍历-递归-返回链表 三、迭代--使用栈 3.1 前序遍历-迭代-使用栈 3.2 中序遍…

【Python3】【力扣题】367. 有效的完全平方数

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;Python函数。num的平方根 或者 num的0.5次幂。 知识点&#xff1a;float.is_integer(...)&#xff1a;判断浮点数的值是否等于整数。也可以&#xff1a;浮点数.is_integer()。 pow(a,b)&…

【SpringCloud】微服务的扩展性及其与 SOA 的区别

一、微服务的扩展性 由上一篇文章&#xff08;没看过的可点击传送阅读&#xff09;可知&#xff0c; 微服务具有极强的可扩展性&#xff0c;这些扩展性包含以下几个方面&#xff1a; 性能可扩展&#xff1a;性能无法完全实现线性扩展&#xff0c;但要尽量使用具有并发性和异步…

【Intel FPGA】D5005 使用笔记

项目总目标&#xff0c;在AFU中实现xx算法DDR 1.FPGA device &#xff1a;1SX280HN2F43E2VG 2 .硬件架构图 3.DDR信息 4.FIM &#xff08;FPAG Interface Manager&#xff09; The FIM contains the FPGA logic to support the accelerators, including the PCIe IP core, …

UDS 相关时间参数

文章目录 UDS 全部时间参数UDS 应用层诊断时间参数1、P2 Client P2 Server P2* Client P2* Server 图例2、S3 Client S3 Server 图例 UDS CNA-TP网络层时间参数1、N_As/N_Ar 图例2、N_Bs 图例3、 N_Br 图例4、N_Cs 图例N_Cr 图例 UDS 网络层流控制时间参数 UDS 全部时间参数 UD…

Java17(LTS Long Term Support)特性

支持JDK17的主流技术框架 spring framework 6.xspringboot 3.xkafka 3.0(不在支持jdk8)jenkins 2.357&#xff08;必须jdk11起步&#xff09;James Gosling表示赶紧弃用Java8&#xff0c;使用性能最好的JDK17Chart GPT也推荐JDK17&#xff0c;从长期到性能来说。 JDK17的特性 …

【古月居《ros入门21讲》学习笔记】15_ROS中的坐标系管理系统

目录 说明&#xff1a; 1. 机器人中的坐标变换 tf功能包能干什么&#xff1f; tf坐标变换如何实现 2. 小海龟跟随实验 安装 ros-melodic-turtle-tf 实验命令 运行效果 说明&#xff1a; 1. 本系列学习笔记基于B站&#xff1a;古月居《ROS入门21讲》课程&#xff0c;且使…