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

学习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.xdnf.cn/news/19766.html

相关文章:

  • TDK InvenSense CH201距离传感器
  • 还在从零开发AI应用?这个项目直接给你500个现成方案!!!
  • Autosar之Det模块
  • 智慧工地如何撕掉“高危低效”标签?三大社会效益重构建筑业价值坐标
  • 贝叶斯定理
  • WAF与CDN在网络安全中的协同作用
  • GitLens VS Code插件测评:助力代码协作高效查提交记录,轻松解决分支管理与代码冲突
  • `<meter> ` 元素 无需 JavaScript/CSS 实现密码强度提示
  • esp32小智ai对话机器人
  • 【字节拥抱开源】 UXO 团队开源 USO: 通过解耦与奖励学习实现的统一风格与主题驱动生成
  • 万和电气卢宇聪:在“慢周期”做本质的事
  • GoLand IDE 无法识别 Go 工作区中的引用,如何解决?
  • 5.kafka集群安装
  • 区间DP .
  • Android U Lmkd源码解析
  • maven 常用指令
  • 二叉树的非递归遍历 | 秋招面试必备
  • Redis分布式缓存
  • RabbitMQ消息堆积问题排查:concurrentConsumers 配置的坑与解决方案
  • js设计模式-职责链模式
  • More Effective C++ 条款24:理解虚拟函数、多继承、虚继承和RTTI的成本
  • VMWare ubuntu24.04安装(安装ubuntu安装)
  • 复杂PDF文档如何高精度解析
  • css3元素倒影效果属性:box-reflect
  • IsaacLab训练机器人
  • uni-app 实现做练习题(每一题从后端接口请求切换动画记录错题)
  • 国内免费低代码软件精选:四款工具助你快速开启数字化转型之路
  • 力扣72:编辑距离
  • windows docker(二) 启动存在的容器
  • 5招教你看透PHP开发框架的生态系统够不够“牛”?