前端学习--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商店里下载

相关文章:
前端学习--React(3)
一、Redux 集中状态管理工具,不需要react即可使用,每个store的数据都是独立于组件之外的 vue小链接:vuex/pinia 基本使用 Redux将数据修改流程分成三个概念,state、action和reducer state - 一个对象 存放我们管理的数据状态 a…...
rotation matrix reflection matrix
文章目录 1. rotation matrix1.1 结论 2. reflection matrix2.1 结论 1. rotation matrix 图像逆时针旋转 θ \theta θ的矩阵 Q r o t a t e [ cos θ − sin θ sin θ cos θ ] (1) Q_{rotate}\begin{bmatrix}\cos\theta&-\sin\theta\\\sin\theta&\c…...
Python基础教程: sorted 函数
嗨喽,大家好呀~这里是爱看美女的茜茜呐 sorted 可以对所有可迭代的对象进行排序操作, sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。 从新排序列表。 👇 👇 👇 更多精彩机密、教程…...
Vue 重写push和replace方法,解决:Avoided redundant navigation to current location
当我们使用编程式路由导航跳转路径时,如果我们两次携带同样的参数进行跳转,会进行页面报错: 那产生这个问题的原因是什么呢? 我们接收并输出调用push方法返回的结果: 会发现这是一个Promise对象 我们都知道ÿ…...
43、vue导出pdf文件,并解决滚动条外内容无法获取的问题
使用插件html2canvas和jspdf插件 下载完两个插件后引入所需要的页面 import html2canvas from "html2canvas" import jsPDF from "jspdf"1、在导出之前将元素的高度或者宽度设置为滚动高度或者宽度,如: el.style.height el.scro…...
牛客 最小公配数 golang版实现
题目请参考: HJ108 求最小公倍数 题解: 在大的数的倍数里面去找最小的能整除另外一个数的数,就是最小公倍数,按照大的来找,循环次数能够降到很少,提升效率 golang实现: package mainimport ("fmt" )func main() {a : …...
用 HLS 实现 UART
用 HLS 实现 UART 介绍 UART 是一种旧的串行通信机制,但仍在很多平台中使用。它在 HDL 语言中的实现并不棘手,可以被视为本科生的作业。在这里,我将通过这个例子来展示在 HLS 中实现它是多么容易和有趣。 因此,从概念上讲…...
华清远见嵌入式学习——网络编程——作业4
作业要求:①使用IO多路复用中的select函数实现TCP并发服务器客户端 ②使用IO多路复用中的poll函数实现TCP并发服务器的服务器端 一、 代码 #include <myhead.h>#define SERPORT 8888 //服务器端口号 #define SERIP "192.168.114.113"…...
【OpenCV实现图像:制作酷炫的动画效果】
文章目录 概要生成背景图添加点动画添加文本显示小结 概要 首先,通过导入必要的库,包括NumPy用于数学运算和Matplotlib库用于数据可视化。随后,创建图形和轴,初始化点的位置,以及编写初始化函数和更新函数。 初始化函…...
CSS鼠标属性篇
属性名:cursor 功能:设置鼠标光标的样式 属性值: pointer:小手move:移动图标text:文字选择器crosshair:十字架wait:等待help:帮助 eg.html{ cursor: wait;}(此处使用css改…...
交直流一体化电源系统测试步骤详解
交直流一体化电源拥有高度适应性,可以用于不同的电力需求领域。但是为了确保其质量和性能,需要对交直流一体化电源进行各项测试以保证正常工作。本文纳米软件将介绍交直流一体化电源的测试方法,以及如何用交直流一体化电源测试系统进行测试。…...
多数据库使用django-apscheduler时,migrate后并不能生成django_apscheduler_djangojob表的问题
先说一下django-apscheduler定时器的使用过程: django-apscheduler基本使用 1.安装django-apscheduler代码如下(示例): pip install django-apscheduler 2.配置settings.py的INSTALLED_APPS代码如下(示例)…...
SPS简单对应分析
前言: 本专栏参考教材为《SPSS22.0从入门到精通》,由于软件版本原因,部分内容有所改变,为适应软件版本的变化,特此创作此专栏便于大家学习。本专栏使用软件为:SPSS25.0 本专栏所有的数据文件请点击此链接下…...
智能井盖传感器建设信息化时代智慧城市
近年来随着信息技术的快速发展和城市化进程的加速推进,智慧城市的概念逐渐成为现实。作为智慧城市生命线建设中的重要组成部分,智能井盖传感器的应用正在为城市的可持续发展和居民的生活质量提供新的解决方案。 智能井盖传感器能够实时监测井盖状态&…...
安装向量数据库milvus及其Attu
前置条件安装docker compose 在宿主机上创建文件目录 mkdir -p /home/sunyuhua/milvus/db mkdir -p /home/sunyuhua/milvus/conf mkdir -p /home/sunyuhua/milvus/etcd下载docker-compose.yml wget https://github.com/milvus-io/milvus/releases/download/v2.2.11/milvus-s…...
量子计算概述
目录 1.量子计算介绍 2.量子计算应用 3.量子计算研究机构 1.量子计算介绍 量子计算是一种遵循量子力学规律调控量子信息单元进行计算的新型计算模式。经典计算使用2进制进行运算,但2进制只有0和1两种状态,而量子计算除了包含0和1两种状…...
校园圈子论坛,交友,帖子内短视频,二手市场,APP小程序H5三端交付,源码交付,支持二开
校园圈子论坛,交友频道,商城,二手市场,活动专区,短视频,从校园生活的方方面面展现出了充满活力和创造力的镜头。这个频道是一个让学生们相互交流、结识新朋友的平台,不仅有交友功能,…...
Request 爬虫的 SSL 连接问题深度解析
SSL 连接简介 SSL(Secure Sockets Layer)是一种用于确保网络通信安全性的加密协议,广泛应用于互联网上的数据传输。在数据爬取过程中,爬虫需要与使用 HTTPS 协议的网站进行通信,这就牵涉到了 SSL 连接。本文将深入研究…...
gin相关操作--一起学习921190764
gin官方文档 https://gin-gonic.com/docs/quickstart/1. 安装 go get -u github.com/gin-gonic/ginhttps://github.com/gin-gonic/gin简单入门 package mainimport ("github.com/gin-gonic/gin""net/http" )func pong(c *gin.Context) {//c.JSON(http.S…...
Linux查看开机启动的服务
在Linux系统中,可以使用不同的命令和工具来查看开机启动的服务。以下是一些常用的方法: systemctl 命令: 使用 systemctl 命令可以查看系统中所有正在运行的服务以及它们的状态。 systemctl list-units --typeservice若要查看某个特定服务的…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
网页端 js 读取发票里的二维码信息(图片和PDF格式)
起因 为了实现在报销流程中,发票不能重用的限制,发票上传后,希望能读出发票号,并记录发票号已用,下次不再可用于报销。 基于上面的需求,研究了OCR 的方式和读PDF的方式,实际是可行的ÿ…...
高保真组件库:开关
一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...
MLP实战二:MLP 实现图像数字多分类
任务 实战(二):MLP 实现图像多分类 基于 mnist 数据集,建立 mlp 模型,实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入,可视化图形数字; 2、完成数据预处理:图像数据维度转换与…...
2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】
1、获取景点详情的请求【my_api.js】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http(/login/getWXSessionKey, {code,avatar}); };//…...
Qt学习及使用_第1部分_认识Qt---Qt开发基本流程
前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...
构建Docker镜像的Dockerfile文件详解
文章目录 前言Dockerfile 案例docker build1. 基本构建2. 指定 Dockerfile 路径3. 设置构建时变量4. 不使用缓存5. 删除中间容器6. 拉取最新基础镜像7. 静默输出完整示例 docker runDockerFile 入门syntax指定构造器FROM基础镜像RUN命令注释COPY复制ENV设置环境变量EXPOSE暴露端…...
Spring是如何实现无代理对象的循环依赖
无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见:mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中,两个或多个对象相互依赖,导致创建过程陷入死循环。以下通过一个简…...
