【React】React18 Hooks 之 useReducer
目录
- useReducer
- 案例1:useReducer不带初始化函数
- 案例2:useReducer带初始化函数
- 注意事项1:dispatch函数不会改变正在运行的代码的状态
- 注意事项2:获取dispatch函数触发后 JavaScript 变量的值
- 注意事项3:触发了reducer,但页面没有更新
React官方文档
useReducer
useReducer是一个 React Hook,可让你向组件添加一个Reducer 。
用法:
const [state, dispatch] = useReducer(reducer, initialArg, init?)
- reducer:指定状态如何更新的 Reducer 函数,接受两个参数state(状态)和action(操作)两个参数,并返回下一个状态
- initialArg:初始值,可以是任何类型的值
- 可选 init:应返回初始状态的初始化函数。如果未指定,则将初始状态设置为initialArg。否则,将初始状态设置为调用的结果init(initialArg)
useReducer返回一个包含两个值的数组:
- state(当前状态):在第一次渲染期间,它被设置为init(initialArg)或initialArg(如果没有init)
- dispatch:该dispatch函数可让您将状态更新为不同的值并触发重新渲染
案例1:useReducer不带初始化函数
步骤:
1、定义一个reducer函数,根据不同的action返回不同的状态
2、组件中调用userReducer(reducer,initialArg)
3、调用dispatch({type:“INC”})通知reducer产生一个新的状态,随后更新UI
const idata = {count:0};
function reducer(state, action) {console.log(state,"state")console.log(action,"action")switch (action.type) {case "INC":return {count:state.count+1}case "DEC":return {count:state.count-1}case "SET":return {count:action.payload}default:return {count:idata}}
}
function App() {const [state, dispatch] = useReducer(reducer, idata);return (<div className="App">this is App{state.count}<button onClick={() => dispatch({ type: "INC" })}>+</button><button onClick={() => dispatch({ type: "DEC" })}>-</button><button onClick={() => dispatch({ type: "SET", payload: 100 })}>update</button></div>);
}export default App;
案例2:useReducer带初始化函数
设置initData为初始化函数,设置state初始状态
#App.js
import Son from "./Son.js";
function App() {return (<div className="App"><Son idata={{count:1}}></Son></div>);}export default App;
#Son.js
import { useReducer } from "react";const initData=()=>{return {count:0}
}function reducer(state, action) {console.log(state,"state")console.log(action,"action")switch (action.type) {case "INC":return {count:state.count+1}case "DEC":return {count:state.count-1}case "SET":return {count:action.payload}default:return initData() }
}const Son = ({idata})=> {console.log(idata,"idata")const [state, dispatch] = useReducer(reducer, idata,initData);return (<div className="App">this is App<div>Count: {state.count}</div><button onClick={() => dispatch({ type: "INC" })}>+</button><button onClick={() => dispatch({ type: "default" })}>default</button><button onClick={() => dispatch({ type: "DEC" })}>-</button><button onClick={() => dispatch({ type: "SET", payload: 100 })}>update</button></div>);
}export default Son;
注意事项1:dispatch函数不会改变正在运行的代码的状态
点击update按钮,handler函数触发之后,页面Count显示为100,但是打印出来state.count为0
dispatch函数不会改变正在运行的代码的状态,更新状态会请求使用新状态值进行另一次渲染,但不会影响state已在运行的事件处理程序中的 JavaScript 变量。
#Son.js
import { useReducer } from "react";
const initData = () => {return { count: 0 }
}
function reducer(state, action) {switch (action.type) {case "INC":return { count: state.count + 1 }case "DEC":return { count: state.count - 1 }case "SET":return { count: action.payload }default:return initData()}
}const Son = ({ idata }) => {
const [state, dispatch] = useReducer(reducer, idata, initData);const handler =()=>{dispatch({ type: "SET", payload: 100 })console.log(state.count,"state")setTimeout(()=>{console.log(state.count,"state")},1000)}return (<div className="App">this is App<div>Count: {state.count}</div><button onClick={() => dispatch({ type: "INC" })}>+</button><button onClick={() => dispatch({ type: "default" })}>default</button><button onClick={() => dispatch({ type: "DEC" })}>-</button><button onClick={() => handler()}>update</button></div >);
}export default Son;
注意事项2:获取dispatch函数触发后 JavaScript 变量的值
执行reducer(state, action)之后,就可以拿到最新的变量的值
const handler =()=>{let action = { type: "SET", payload: 100 };dispatch(action)console.log(state,"state") //打印0setTimeout(()=>{console.log(state,"state") //打印0},1000)const nextState = reducer(state, action);console.log(nextState,'nextState') //打印100}
注意事项3:触发了reducer,但页面没有更新
直接更改状态中的对象或数组,并不会重新渲染。因为下一个状态等于前一个状态,则React 将忽略您的更新Object.is,指向的还是同一个引用地址。所以需要始终更新状态中的对象和状态中的数组。如下:
function reducer(state, action) {switch (action.type) {case 'incremented_age': {// ✅ Correct: creating a new objectreturn {...state,age: state.age + 1};}case 'changed_name': {// ✅ Correct: creating a new objectreturn {...state,name: action.nextName};}// ...}
}相关文章:
【React】React18 Hooks 之 useReducer
目录 useReducer案例1:useReducer不带初始化函数案例2:useReducer带初始化函数注意事项1:dispatch函数不会改变正在运行的代码的状态注意事项2:获取dispatch函数触发后 JavaScript 变量的值注意事项3:触发了reducer&am…...
【cocos creator】2.4.x实现简单3d功能,点击选中,旋转,材质修改,透明材质
demo下载:(待审核) https://download.csdn.net/download/K86338236/89527924 const {ccclass, property } = cc._decorator;const enum box_color {NORMAL = 0,DASHED_LINE = 1,//虚线TRANSLUCENT = 2,//半透明 }@ccclass export default class main extends cc.Component {…...
Android EditText+ListPopupWindow实现可编辑的下拉列表
Android EditTextListPopupWindow实现可编辑的下拉列表 📖1. 可编辑的下拉列表✅步骤一:准备视图✅步骤二:封装显示方法✅步骤三:获取视图并监听 📖2. 扩展上下箭头✅步骤一:准备上下箭头icon图标✅步骤二&…...
dify/api/models/task.py文件中的数据表
源码位置:dify/api/models/task.py CeleryTask 表结构 字段英文名数据类型字段中文名字备注idIntegerID自增主键,任务ID序列task_idString任务ID唯一任务标识statusString状态默认值为 PENDINGresultPickleType结果可为空date_doneDateTime完成日期默认…...
hdu物联网硬件实验3 按键和中断
学院 班级 学号 姓名 日期 成绩 实验题目 按键和中断 实验目的 实现闪灯功能转换 硬件原理 无 关键代码及注释 /* Button Turns on and off a light emitting diode(LED) connected to digital pin 13, when pressing a pushbutton attached…...
pytorch通过 tensorboardX 调用 Tensorboard 进行可视化
示例 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transformsfrom tensorboardX import SummaryWriter# 定义神经网络模型 class SimpleCNN(nn.Module):def __init__(self):…...
linux查看目录下的文件夹命令,find 查找某个目录,但是不包括这个目录本身?
linux查看目录下的文件夹命令,find 查找某个目录,但是不包括这个目录本身? Linux中查看目录下的文件夹的命令是使用ls命令。ls命令用于列出指定目录中的文件和文件夹。通过不同的选项可以实现显示详细信息、按照不同的排序方式以及使用不同的…...
单一设备上的 2 级自动驾驶:深入探究 Openpilot 的奥秘
Level 2 Autonomous Driving on a Single Device: Diving into the Devils of Openpilot 单一设备上的 2 级自动驾驶:深入探究 Openpilot 的奥秘 Abstract Equipped with a wide span of sensors, predominant autonomous driving solutions are becoming more m…...
向github远程仓库中push,要求使用token登录
Support for password authentication was removed on August 13, 2021. Please use a personal access token instead. 如上,当向github远程仓库push时,输入github的用户名和密码出现如上错误,要求使用token登录,此时只需要用户…...
最全windows提权总结(建议收藏)
当以低权用户进去一个陌生的windows机器后,无论是提权还是后续做什么,第一步肯定要尽可能的搜集信息。知己知彼,才百战不殆。 常规信息搜集 systeminfo 查询系统信息hostname 主机名net user 查看用户信息netstat -ano|find "3389&quo…...
Could not find Chrome (ver.xxxxx). This can occur if either\n
文章目录 错误解决方法 错误 Could not find Chrome (ver. 119.0.6045.105). This can occur if either\n 1. you did not perform an installation before running the script (e.g. npx puppeteer browsers install chrome) or\n 2. your cache path is incorrectly configu…...
Conmi的正确答案——ESP32-C3开启安全下载模式
IDF版本:4.4.7 注意事项:一旦烧录“安全下载模式”,模组将无法被读取或清理,只能通过eclipse原项目烧录程序进行重新烧录,无法再烧录其他固件。 20240703110201——追加解法,暂时无法解安全下载模式 &…...
从零开始实现大语言模型(一):概述
1. 前言 大家好,我是何睿智。我现在在做大语言模型相关工作,我用业余时间写一个专栏,给大家讲讲如何从零开始实现大语言模型。 从零开始实现大语言模型是了解其原理及领域大语言模型实现路径的最好方法,没有之一。已有研究证明&…...
科普文本分类背后的数学原理——最新版《数学之美》第14、15章读书笔记
新闻分类,或广义上的文本分类,其核心任务是根据文本内容将相似文本聚合在同一类别中。在新闻领域,这意味着将报道划分为财经、体育、军事等不同主题。人类执行此任务时,通过阅读和理解新闻的主旨来进行归类。然而,作者…...
华为云生态和快速入门
华为云生态 新技术催生新物种,新物种推动新生态 数字技术催生各类运营商去重塑并颠覆各行业的商业模式 从业务层面看,企业始终如一的目标是业务增长和持续盈利,围绕这些目标衍生出提质、增效、降本、安全、创新和合规的业务诉求,…...
卷积神经网络——LeNet——FashionMNIST
目录 一、整体结构二、model.py三、model_train.py四、model_test.py GitHub地址 一、整体结构 二、model.py import torch from torch import nn from torchsummary import summaryclass LeNet(nn.Module):def __init__(self):super(LeNet,self).__init__()self.c1 nn.Conv…...
k8s-第十二节-DaemonSet
DaemonSet是什么? DaemonSet 是一个确保全部或者某些节点上必须运行一个 Pod的工作负载资源(守护进程),当有node(节点)加入集群时, 也会为他们新增一个 Pod。 下面是常用的使用案例: 可以用来部署以下进程的pod 集群守护进程,如Kured、node-problem-detector日志收集…...
Mysql-内置函数
一.什么是函数? 函数是指一段可以直接被另外一段程序调用的程序或代码。 mysql内置了很多的函数,我们只需要调用即可。 二.字符串函数 MySQL中内置了很多字符串函数: 三.根据需求完成以下SQL编写 由于业务需求变更,企业员工的工号,统一为5位数,目前不足5位数的全…...
新浪API系列:支付API打造无缝支付体验,畅享便利生活(3)
在当今数字化时代,支付功能已经成为各类应用和平台的必备要素之一。作为开发者,要构建出安全、便捷的支付解决方案,新浪支付API是你不可或缺的利器。新浪支付API提供了全面而强大的接口和功能,帮助开发者轻松实现在线支付的集成和…...
终于弄明白了什么是EI!
EI是Engineering Index的缩写,中文意为“工程索引”,是由美国工程信息公司(Engineering Information, Inc.)编辑出版的著名检索工具。它始创于1884年,拥有超过一个世纪的历史,是全球工程界最权威的文献检索系统之一。EI虽然名为“…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
