React第十一章(useReducer)
useReducer
useReducer是React提供的一个高级Hook,没有它我们也可以正常开发,但是useReducer可以使我们的代码具有更好的可读性,可维护性。
useReducer 跟 useState 一样的都是帮我们管理组件的状态的,但是呢与useState不同的是 useReducer 是集中式的管理状态的。
用法

const [state, dispatch] = useReducer(reducer, initialArg, init?)
参数:
-
reducer是一个处理函数,用于更新状态, reducer 里面包含了两个参数,第一个参数是state,第二个参数是action。reducer会返回一个新的state。 -
initialArg是state的初始值。 -
init是一个可选的函数,用于初始化state,如果编写了init函数,则默认值使用init函数的返回值,否则使用initialArg。
返回值:
useReducer 返回一个由两个值组成的数组:
当前的 state。初次渲染时,它是 init(initialArg) 或 initialArg (如果没有 init 函数)。
dispatch 函数。用于更新 state 并触发组件的重新渲染。
import { useReducer } from 'react';
//根据旧状态进行处理 oldState,处理完成之后返回新状态 newState
//reducer 只有被dispatch的时候才会被调用 刚进入页面的时候是不会执行的
//oldState 任然是只读的
function reducer(oldState, action) {// ...return newState;
}function MyComponent() {const [state, dispatch] = useReducer(reducer, { age: 42,name:'小满' });// ...
计数器案例
初始状态 (initialState):
const initialState = { count: 0 };
这里定义了一个初始状态对象,包含一个 count 属性,初始值为 0。
reducer 函数:
function reducer(state, action) {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:throw new Error();}
}
- reducer 是一个用来根据不同的 action 来更新状态的纯函数。
- 它接收当前状态 (state) 和一个动作对象 (action),根据 action.type 来决定如何更新 state。
- 如果 action.type 是 ‘increment’,则 count 增加 1;如果是 ‘decrement’,则 count 减少 1。
- 如果 action.type 不匹配任何已定义的情况,则抛出一个错误。
App 组件:
const App = () => {const [state, dispatch] = useReducer(reducer, initialState);return (<>Count: {state.count}<button onClick={() => dispatch({ type: 'decrement' })}>-</button><button onClick={() => dispatch({ type: 'increment' })}>+</button></>);
}
export default App;
- 当点击 “-” 按钮时,调用 dispatch({ type: ‘decrement’ }),使 count 减少。
- 当点击 “+” 按钮时,调用 dispatch({ type: ‘increment’ }),使 count 增加。
购物车案例
- 初始数据 (initData):
const initData = [{ name: '小满(只)', price: 100, count: 1, id: 1, isEdit: false },{ name: '中满(只)', price: 200, count: 1, id: 2, isEdit: false },{ name: '大满(只)', price: 300, count: 1, id: 3, isEdit: false }
]
- initData 是一个数组,表示初始的商品列表。每个商品有以下属性:
- name: 商品的名称(例如 “小满(只)”)。
- price: 单价(例如 100)。
- count: 数量,默认为 1。
- id: 商品的唯一标识符。
- isEdit: 表示该商品名称是否处于编辑状态,默认为 false。
- 类型定义 (List 和 Action):
type List = typeof initData
interface Action { type: "ADD" | "SUB" | 'DELETE' | 'EDIT' | 'UPDATE_NAME', id: number, newName?: string
}
- List 是商品数组的类型,直接从 initData 推断。
- Action 接口定义了不同的操作类型:
- ADD: 增加某个商品的数量。
- SUB: 减少某个商品的数量。
- DELETE: 删除某个商品。
- EDIT: 切换某个商品的编辑状态。
- UPDATE_NAME: 更新某个商品的名称。
- id: 需要操作的商品的 id。
- newName: 用于 UPDATE_NAME 操作时,新的商品名称。
- Reducer 函数 (reducer):
function reducer(state: List, action: Action) {const item = state.find(item => item.id === action.id)!switch (action.type) {case "ADD":item.count++return [...state]case "SUB":item.count--return [...state]case "DELETE":return state.filter(item => item.id !== action.id)case "EDIT":item.isEdit = !item.isEditreturn [...state]case "UPDATE_NAME":item.name = action.newName!return [...state]default:return state}
}
reducer 函数根据传入的 action 更新商品列表的状态。
查找到要操作的商品 item。
对不同的 action.type 执行相应操作:
- ADD: 将商品数量增加 1。
- SUB: 将商品数量减少 1。
- DELETE: 删除指定商品。
- EDIT: 切换商品的编辑状态(输入框显示或隐藏)。
- UPDATE_NAME: 更新商品的名称。
- App 组件:
function App() {let [data, dispatch] = useReducer(reducer, initData)return (<><table cellPadding={0} cellSpacing={0} width={600} border={1}><thead><tr><th>物品</th><th>价格</th><th>数量</th><th>操作</th></tr></thead><tbody>{data.map((item) => {return (<tr key={item.id}><td align='center'>{item.isEdit ? <input onBlur={e => dispatch({ type: "EDIT", id: item.id })} onChange={e => dispatch({ type: "UPDATE_NAME", id: item.id, newName: e.target.value })} value={item.name} /> : <span>{item.name}</span>}</td><td align='center'>{item.price * item.count}</td><td align='center'><button onClick={() => dispatch({ type: "SUB", id: item.id })}>-</button><span>{item.count}</span><button onClick={() => dispatch({ type: "ADD", id: item.id })}>+</button></td><td align='center'><button onClick={() => dispatch({ type: "EDIT", id: item.id })}>编辑</button><button onClick={() => dispatch({ type: "DELETE", id: item.id })}>删除</button></td></tr>)})}</tbody><tfoot><tr><td colSpan={3}></td><td align='center'>总价:{data.reduce((prev, next) => prev + next.price * next.count, 0)}</td></tr></tfoot></table></>)
}
- App 组件使用 useReducer 来管理 data 状态,它从 initData 初始化,并通过 dispatch 分发动作来改变商品列表。
- 商品列表通过 table 渲染,每个商品显示以下信息:
- 物品:如果该商品的 isEdit 为 true,显示一个输入框用于修改名称;否则显示商品名称。
- 价格:显示商品的总价(price * count)。
- 数量:显示商品的数量,提供 - 和 + 按钮来减少或增加数量。
- 操作:提供 编辑 按钮切换名称编辑状态,删除 按钮可以删除该商品。
- tfoot 部分显示购物车的总价,通过 reduce 方法计算所有商品的总价。
相关文章:
React第十一章(useReducer)
useReducer useReducer是React提供的一个高级Hook,没有它我们也可以正常开发,但是useReducer可以使我们的代码具有更好的可读性,可维护性。 useReducer 跟 useState 一样的都是帮我们管理组件的状态的,但是呢与useState不同的是 useReducer…...
VUE3实现古典音乐网站源码模板
文章目录 1.设计来源1.1 网站首页页面1.2 古典音乐页面1.3 著名人物页面1.4 古典乐器页面1.5 历史起源页面1.6 登录页面1.7 注册页面 2.效果和源码2.1 动态效果2.2 目录结构 源码下载万套模板,程序开发,在线开发,在线沟通 作者:xc…...
1.nginx安装【Docker】
一、 拉取 最新 nginx 镜像 docker pull nginx二、 拷贝配置文件 2.1 目的 【数据持久化】容器被删除时,它内部的所有数据也会丢失。通过将数据目录挂载到宿主机,可以确保重要数据得到持久化保存 【方便数据管理和调试】通过卷挂载,可以直接…...
Linux -- 共享内存(1)
目录 共享内存 共享内存相关函数 ftok 函数 -- 获取 key 值 什么是 key? 如何生成 key ? 参数: 返回值: 封装: shmget 函数 -- 获取 shmid 值 什么是 shmid? shmid 和 key 的区别? …...
冒泡排序和二分查找--go
冒泡排序的逻辑 二分查找的逻辑 func bubbleSort(arr *[5]int){//冒泡排序fmt.Println(*arr)temp : 0for j : len(*arr); j > 0; j-- {for i : 0; i < j-1; i {temp (*arr)[i]if((*arr)[i] > (*arr)[i1]){(*arr)[i] (*arr)[i1](*arr)[i1] temp}}} }func binaryF…...
springboot RedisTemplate支持多个序列化方式
前提纪要:因为业务变动,需要在原先只支持protobuf的前提序列化的前提下,新增正常的序列化读取数据所以在原先的基础上进行优化。文章用于记忆。 话不多说直接上代码 Configuration AutoConfigureAfter(RedisAutoConfiguration.class) Import…...
开源项目-拍卖管理系统
哈喽,大家好,今天主要给大家带来一个开源项目-拍卖管理系统 拍卖管理系统主要有拍卖品管理,我的拍卖,拍卖详情,拍卖品信息修改,发布拍卖品等功能 登录 拍卖商品管理 主要用于查看、竞拍拍卖商品的信息 我…...
Python小游戏14——雷霆战机
首先,你需要确保安装了Pygame库。如果你还没有安装,可以使用pip来安装: bash pip install pygame 代码如下: python import pygame import sys import random # 初始化Pygame pygame.init() # 设置屏幕大小 screen_width 800 scr…...
81页PPT | 企业数字化底座与数字化转型方案
方案内容涵盖了企业数字化转型的议程、集团管理分析类应用建设的现状与问题、数字化建设的目标、预期收益、总体架构、数据产生层、数据交换层、数据存储层、数据应用层、数据管控层等多个方面。方案详细描述了数据从产生、交换、存储到应用的全过程,以及如何通过数…...
R语言笔记(五):Apply函数
文章目录 一、Apply Family二、apply(): rows or columns of a matrix or data frame三、Applying a custom function四、Applying a custom function "on-the-fly"五、Applying a function that takes extra arguments六、Whats the return argument?七、Optimized…...
Newsqueak:在 Go 之前的一门语言
写在前面 学习一个东西的一种很好的方法,就是去了解这个东西的历史。在我们学习 Go 的过程中,同样也可以去了解下在 Go 之前的一些事情。 内容 Rob Pike 是 Go 语言的作者之一,早年他在贝尔实验室工作,也是 Unix 团队的成员。 …...
世界酒中国菜与另可数字平台达成战略合作
世界酒中国菜与另可数字平台达成战略合作,共推行业发展新高度 近日,在行业内引起广泛关注的“世界酒中国菜”项目,与“另可”数字平台成功举行了战略合作签约仪式。这一重要合作不仅是双方发展历程中的重要里程碑,更是继世界酒中…...
ElasticSearch基础篇——概念讲解,部署搭建,使用RestClient操作索引库和文档数据
目录 一、概念介绍 二、Elasticsearch的Docker容器安装 2.1拉取elasticsearch的镜像文件 2.2运行docker命令启动容器 2.3通过访问端口地址查看部署情况 三、安装Kibana容器 3.1拉取Kibana镜像容器指令(默认拉取最新版本): 3.2拉取完…...
k8s 二进制部署安装(一)
目录 环境准备 初始化操作系统 部署docker 引擎 部署 etcd 集群 准备签发证书环境 部署 Master01 服务器相关组件 apiserver scheduler controller-manager.sh admin etcd 存储了 Kubernetes 集群的所有配置数据和状态信息,包括资源对象、集群配置、元数据…...
115页PPT华为管理变革:制度创新与文化塑造的核心实践
集成供应链(ISC)体系 集成供应链(ISC)体系是英文Integrated Supply Chain的缩写,是一种先进的管理思想,它指的是由相互间提供原材料、零部件、产品和服务的供应商、合作商、制造商、分销商、零售商、顾客等…...
ubuntu限制网速方法
sudo apt-get install trickle sudo trickle -d <下载速度> -u <上传速度> <命令>例如git clone sudo trickle -d 1024 git clone http://xxxxxxxxxx.git如果想简化指令可以在bashrc中添加如下指令 alias gitttrickle -u 1024 gitgitt为自定义 使用方法&am…...
三品PLM研发管理系统:企业产品研发过程的得力助手
三品PLM系统:全方位赋能企业产品生命周期管理的优选方案 在当今竞争激烈的市场环境中,产品生命周期管理PLM系统已成为企业实现高效、灵活和创新产品开发的关键工具。PLM系统集成了信息技术、先进管理思想与企业业务流程,旨在帮助企业优化产品…...
PyCharm 添加不了 Anaconda 环境
经常会遇到 PyCharm 无法添加新创建的 Anaconda 环境, Setting --> Python Interpreter --> Add Python Interperter --> Conda Environment 中为空,即使打开右侧文件夹路径按钮,选择新创建的 conda 环境,也无法找到 pyt…...
Leetcode 二叉树的右视图
好的,我来用中文详细解释这段代码的算法思想。 问题描述 题目要求给定一个二叉树的根节点,从树的右侧看过去,按从上到下的顺序返回看到的节点值。即,我们需要找到每一层的最右侧节点并将其加入结果中。 算法思想 这道题可以通…...
console.log(“res.data = “ + JSON.stringify(res.data));
res.data[object Object] 说明你在控制台打印 res.data 时,它是一个 JavaScript 对象,而不是字符串。这种情况下,console.log 输出的 [object Object] 表示它无法直接显示对象的内容。 要查看 res.data 的实际内容,你需要将其转换…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...
npm安装electron下载太慢,导致报错
npm安装electron下载太慢,导致报错 背景 想学习electron框架做个桌面应用,卡在了安装依赖(无语了)。。。一开始以为node版本或者npm版本太低问题,调整版本后还是报错。偶尔执行install命令后,可以开始下载…...
智能体革命:企业如何构建自主决策的AI代理?
OpenAI智能代理构建实用指南详解 随着大型语言模型(LLM)在推理、多模态理解和工具调用能力上的进步,智能代理(Agents)成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同,智能代理能够自主执行工…...
