【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虽然名为“…...
WordPress建站避坑指南:Ubuntu服务器常见权限问题与安全配置
WordPress建站避坑指南:Ubuntu服务器常见权限问题与安全配置 引言:为什么你的WordPress网站总出问题? 每次看到新手开发者兴奋地宣布"我的WordPress网站上线了",我都忍不住想问:你真的检查过文件权限了吗&am…...
AgentCPM深度研报助手C语言文件操作实战:批量处理本地研报文本文件
AgentCPM深度研报助手C语言文件操作实战:批量处理本地研报文本文件 你是不是也遇到过这样的场景?手头有一堆下载好的行业研报,有PDF,有TXT,堆在文件夹里。想快速了解每份报告的核心观点,但一份份打开看&am…...
Phi-3-mini-128k-instruct实战案例:中小企业技术文档自动解析与结构化提取
Phi-3-mini-128k-instruct实战案例:中小企业技术文档自动解析与结构化提取 1. 项目背景与价值 对于中小企业而言,技术文档管理一直是个令人头疼的问题。工程师们经常需要从大量PDF、Word文档中提取关键信息,手动整理成结构化数据。这个过程…...
SOONet实战教程:结合Whisper提取音频文本,构建音视频联合语义定位Pipeline
SOONet实战教程:结合Whisper提取音频文本,构建音视频联合语义定位Pipeline 1. 项目概述 今天给大家介绍一个特别实用的技术方案:如何用SOONet视频时序定位系统,结合Whisper语音识别,构建一个完整的音视频语义定位pip…...
医美私信获客新范式:快商通AI私信机器人如何实现高效客户转化
医美私信获客新范式:快商通AI私信机器人如何实现高效客户转化 关键要点: 医美行业夜间咨询流失率高达 78% ,响应不及时是主要原因 快商通AI私信机器人实现 724小时 智能接待,开口率从 22% 提升至 100% 实际应用数据显示࿰…...
手把手教你用Whistle给SSE/流式接口做Mock:从复制URL到完整响应的保姆级配置
从零构建SSE接口Mock环境:Whistle流式数据模拟实战指南 当你在开发一个实时聊天应用或AI对话界面时,Server-Sent Events (SSE)技术能提供持续的数据流,但测试环境的搭建往往令人头疼。想象一下,你的前端代码需要处理/api/chat这样…...
本地图片检索新方案:ImageSearch完全使用指南
本地图片检索新方案:ImageSearch完全使用指南 【免费下载链接】ImageSearch 基于.NET8的本地硬盘千万级图库以图搜图案例Demo和图片exif信息移除小工具分享 项目地址: https://gitcode.com/gh_mirrors/im/ImageSearch 当你的电脑中存储了成千上万张图片&…...
避坑指南:Cypress CYT4B的Mcal CAN配置,这5个参数配错直接通信失败
Cypress CYT4B的Mcal CAN配置实战:5个致命参数解析与避坑策略 实验室里,示波器上的CAN波形杂乱无章,工程师反复检查硬件连接却始终无法建立稳定通信——这可能是许多嵌入式开发者调试CYT4B系列芯片时的真实写照。当硬件排查无果后,…...
2026年3月27日NSSCTF之[SWPUCTF 2021 新生赛]ez_unserialize
[SWPUCTF 2021 新生赛]ez_unserialize 开启环境,进入并查看,可以看到一个动图,选择查看网页源码,得到 看到有隐藏信息,根据隐藏信息可以猜测,可以利用robots协议查看相关信息,访问得到 可以得…...
3个步骤打造静音散热系统:FanControl 262版智能风扇调控方案全解析
3个步骤打造静音散热系统:FanControl 262版智能风扇调控方案全解析 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub…...
