当前位置: 首页 > news >正文

学习React-8-useImmer

useImmer

useImmer是基于 immer 库实现的一个 React Hook,它让你可以像修改可变数据一样来修改不可变数据。immer 是一个不可变的数据结构库,完全符合 React 的不可变性原则。

特点
  • 可变式写法:你可以像修改可变数据一样编写代码,但实际上是在生成新的不可变数据
  • 类型安全:完全支持 TypeScript,提供良好的类型推断
  • 性能优化:使用结构共享,只修改变化的部分,其他部分保持引用不变
实现原理
immer 的核心是使用 Proxy 对象来拦截对原始数据的修改操作。当你在 produce 函数中修改数据时,immer 会记录这些修改,然后基于原始数据生成一个新的不可变对象。
使用

因为这并不是React官方的包,所以需要下载 npm install immer use-immer

小栗子

useImmer

import React from 'react';
import { useImmer, useImmerReducer } from 'use-immer';interface User {name: stringage: numberhobby: Array<string>}
interface UseImmerProps {pUser: User;
}const UseImmer: React.FC<UseImmerProps> = (props) => {const [user, updateUser] = useImmer<User>(props.pUser);const handleIncreaseAge = () => {updateUser(draft => {draft.age += 1;});};// 操作对象的值const handleSetName = (name: string) => {updateUser(draft => {draft.name = name;});};// 操作数组的值const handleHobby = (name: string) => {updateUser(draft => {draft.hobby.push(name)})}return (<div><p>User: {user.name}, Age: {user.age}</p>{user.hobby.map((item, index) => {return <p key={`${item}_${index}`}>{item}</p>;})}<button onClick={handleIncreaseAge}>Increase Age</button><button onClick={() => handleSetName('黑子')}>Change name</button><button onClick={() => handleHobby('跳舞')}>add hobby</button></div>);
};export default UseImmer;// App调用
<UseImmer pUser={{name: 'kun', age: 18, hobby: ['唱歌'] }}></UseImmer>

useImmerReducer


interface State {count: number;
}
type Action = | { type: 'INCREMENT' }| { type: 'DECREMENT' }const initState = {count: 0
}
const counterReducer = (state: State, action: Action) => {switch (action.type) {case 'INCREMENT':state.count += 1;break;case 'DECREMENT':state.count -= 1;break;}
}
const UseImmer: React.FC<UseImmerProps> = (props) => {const [state, dispatch] = useImmerReducer(counterReducer, initState)return (<div><button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button><p>Count: {state.count}</p><button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button></div>);
};export default UseImmer;
useState和useImmer对比
维度useState(原生)useImmer(基于 Immer)
引入成本React 自带需安装 use-immer
基本类型✅ 直接 setCount(c => c + 1)✅ 同样写法
简单对象 / 数组❗ 手动展开、拼接、拷贝✅ 直接 draft.x.y = z
深层嵌套结构❌ 层层解构,代码冗长易错✅ 按可变方式书写即可
不可变性保证开发者完全自控Immer 内部自动生成新引用
样板代码量
调试可读性reducer / switch 可读性一般逻辑扁平,更具命令式直觉
性能(简单场景)最快稍慢(Immer Proxy 开销)
性能(复杂场景)可能因多次浅拷贝浪费Immer 结构共享,反而更优
代码对比

useState —— 更新深层字段:

setState(prev => ({...prev,user: {...prev.user,address: {...prev.user.address,city: 'Shanghai'}}
}));

useImmer —— 同一段逻辑:

updateState(draft => {draft.user.address.city = 'Shanghai';
});
http://www.dtcms.com/a/363427.html

相关文章:

  • Linux---初始Linux及其基本指令
  • 02-Media-2-ai_rtsp.py 人脸识别加网络画面RTSP推流演示
  • 【51单片机】【protues仿真】基于51单片机脉搏体温检测仪系统
  • JavaScript》》JS》》ES6》》 数组 自定义属性
  • HTTP发展历程
  • RPC和HTTP的区别?
  • HttpHeadersFilter
  • GPT-Realtime 弹幕TTS API 低延迟集成教程
  • 网络原理——HTTP/HTTPS
  • 【MySQL体系结构详解:一条SQL查询的旅程】
  • 分布式中防止重复消费
  • 计算机视觉与深度学习 | 视觉里程计技术全解析:定义、原理、与SLAM的关系及应用场景
  • STM32之SPI详解
  • Linux《进程信号(上)》
  • mit6.031 2023spring 软件构造 笔记 Specification
  • 【XR硬件系列】Apple Vision Pro 完全解读:苹果为我们定义了怎样的 “空间计算” 未来?
  • springboot项目使用websocket功能,使用了nginx反向代理后连接失败问题解决
  • 集采与反腐双重压力下,医药销售的破局之道:从资源依赖到价值重构
  • DASK shuffle任务图分析
  • 阅读Linux 4.0内核RMAP机制的代码,画出父子进程之间VMA、AVC、anon_vma和page等数据结构之间的关系图。
  • 解密llama.cpp CUDA后端:512 token大模型批处理的异步流水线架构
  • 【llama.cpp】qwen2_vl_surgery.py详解
  • 应用层:HTTP/HTTPS协议
  • 2025年- H109-Lc1493. 删掉一个元素以后全为 1 的最长子数组(双指针)--Java版
  • 软件测试小结(1)
  • 【完整源码+数据集+部署教程】粘土石实例分割系统源码和数据集:改进yolo11-LVMB
  • MVP架构深层剖析-从六大设计原则的实现角度到用依赖注入深度解耦
  • 安全芯片助力游戏设备防抄板
  • 「Windows自动化之王:PowerShell极简美学」​
  • 微信小程序 navigateTo 栈超过多层后会失效