Immer编写简洁的更新state逻辑

news2024/11/28 16:04:52

react官网推荐库use-immer:https://www.npmjs.com/package/use-immer
引入:import { useImmer } from "use-immer";

优点:

  1. 简化代码: 只需要关注需要变动的部分,而 immer 本身将在后台处理其余部分。
  2. 学习成本和替换代价小

一、对象

假如现在有一个嵌套结构的对象:

const personList = {
  name: 'Niki de Saint Phalle',
  artwork: {
    title: 'Blue Nana',
    city: 'Hamburg',
    image: {
        url: 'https://i.imgur.com/Sd1AgUOm.jpg',
        alt: 'test',
    }
  }
}

正常写法

const [person, setPerson] = 
    useState(personList)

setPerson({
  ...person, 
  artwork: { 
    ...person.artwork, 
    image: {
      ...person.artwork.image,
      alt: 'test1'
    }
  }
});

使用use-immer:

const [person, updatePerson] = 
    useImmer(personList)

updatePerson(draft => {
  draft.artwork.image.alt = 'test1';
});
  • draft:一种特殊类型的对象,Proxy,可以保留一份之前的对象
  • Immer 找出哪些部分draft已被更改,并生成一个包含您的编辑的全新对象。

二、数据的双向绑定:immer中的核心 api ——produce

Immer.jsmobx 的作者写的一个 Immutable(不可变数据) 库,核心实现是利用 ES6 的proxy,几乎以最小的成本实现了JavaScript的不可变数据结构。

[图片]

api介绍:

produce(baseState, recipe: (draftState) => void): nextState

基本概念:

  • baseState:被操作对象的最初状态
  • draftState: 根据currentState生成的草稿、是currentState的代理、对draftState所有的修改都被记录并用于生成nextState。在此过程中,currentState不可变
  • recipe:用于操作draftState的函数
  • nextState: 根据draftState生成的最终状态
  • produce: 用于生成nextState或者producer的函数
import produce from "immer"

const baseState = personList

const nextState = produce(baseState, draftState => {
    draftState.artwork.image.alt = 'test1';
})

draftState的修改最终都会体现在nextState,但并不会修改baseState
需要注意的是nextStatebaseState共享未修改的部分。通过produce生成的nextState是被冻结的(使用Object.freeze实现,仅冻结nextStatecurrentState相比更改的部分),直接修改nextstate会报错。

2.1 Proxy 对象

用于创建一个对象的代理,实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)
Proxy 对象接受两个参数,

  • 第一个参数:需要操作的对象
  • 第二个参数是设置对应拦截的属性,支持getset(劫持了对应元素的读和写),能够在其中进行一些操作,最终返回一个 Proxy 对象实例
const handle = {     
    get(target, key) {       
        // 这里的 target 就是 Proxy 的第一个参数对象
        console.log('proxy get key', key)       
        return '返回1'     
    },     
    set(target, key, value) {       
        console.log('proxy set key', value)     
    }   
}   
const target = {a:1}   
const p = new Proxy(target, handle)   
p.a = 2 // 所有设置操作都被转发到了 set 方法内部 

2.2 produce

源码:

[图片]

主流程主要根据base创建draft对象、执行用户传入的recipe拦截读写操作,走到自定义的gettersetter最后再解析组装结果返回给用户。

2.3 hook——useImmer

use-Immer库把上述setState+produce的用法封装起来。
它接收一个初始状态,返回一个数组。
数组解构出的第一个值为当前状态,第二个值为状态更新函数(produce 中的 recipe )。

“一”中修改后的🌰:

// 一般将 setxxx => updatexx
const [person, updatePerson] = useImmer(personList)

// recipe:用于操作draftState的函数
updatePerson(draft => {
  draft.artwork.image.alt = 'test1';
});

三、数组

在 JavaScript 中,数组只是另一种对象,应该将处于 React 状态的数组视为只读,
每次您想更新一个数组时,您都需要将一个新数组传递给您的状态设置函数。

在这里插入图片描述

使用immer: 可以使用两列的方法

const [artists, setArtists] = useState([]);

举例

 setArtists( 
  [ 
    ...artists, 
    { id: '1', name: name } 
  ]
);

或者

 updateMyList(draft => {
  //push/unshift
  draft.push({ id: '1', name: name })
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/626647.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的实践应用

查看原文>>>双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的实践应用 目录 第一讲、DNDC模型介绍 第二讲、DNDC初步操作 第三讲、遥感和GIS基础 第四讲、DNDC气象数据 第五讲、DNDC土地数据 第六讲、DNDC土壤数据 …

【C语言】算法学习·Dijkstra算法详解

目录 Dijkstra算法设计 Dijkstra算法简介 Dijkstra算法的基本思想 Dijkstra贪心策略 完美图解 伪代码详解 完整代码 算法解析及优化拓展 ​使用优先队列的完整代码 Dijkstra算法设计 Dijkstra算法简介 Dijkstra算法是解决**单源最短路径**问题的**贪心算法** …

2021年国赛高教杯数学建模C题生产企业原材料的订购与运输解题全过程文档及程序

2021年国赛高教杯数学建模 C题 生产企业原材料的订购与运输 原题再现 某建筑和装饰板材的生产企业所用原材料主要是木质纤维和其他植物素纤维材料,总体可分为 A,B,C 三种类型。该企业每年按 48 周安排生产,需要提前制定 24 周的原材料订购和…

如何在 javascript 中按属性值查找数组中的对象

文章目录 使用 find() 方法按属性值在数组中查找对象使用 filter() 方法按属性值查找数组中的对象使用 JavaScript for 循环按属性值查找数组中的对象使用 JavaScript for...in 循环按属性值查找数组中的对象 数组指的是值的有序列表,每个值称为由索引指定的元素。 …

这所西安的985专硕爆冷,保护一志愿,过线即上岸!

本期为大家整理热门院校“西北工业大学”的择校分析,这个择校分析专题会为大家结合:初试复试占比、复试录取规则(是否公平)、往年录取录取名单、招生人数、分数线、专业课难度等进行分析。希望能够帮到大家! –所有数据来源于研招…

Plot、Scatter、Subplot函数用法

目 录 一、Plot()函数 二、Scatter()函数 三、Subplot()函数 一、Plot()函数 格式:matplotlib.pyplot.plot(x,y,format_string.**kwargs) 说明: x:x轴数据,列表或数组,可选(注:当绘制多条曲线时,不能省…

IT 系统巡检必须关注的指标总结

1. 系统整体架构 以下内容作为基本 IT 系统信息被首先调查记录,供分析参考使用。 ● 网络设备配置 ---设备型号, IOS 版本, 模块型号和数量,用途 ● 存储系统配置 ---设备型号, IO 带宽, Cache 容量,磁盘数量,接入模式,存储容…

Go项目配置管理工具---Viper

目录 Viper概述前言功能viper配置优先级 从Viper中获取值读取配置文件注册和使用别名 把值写入Viper设置默认值使用Set方法设置值把配置信息写入配置文件从io.Reader中读取配置信息到viper 监控Viper文件 Viper概述 前言 对于现代应用程序,尤其大中型的项目来说&a…

【MySQL】Mycat

文章目录 什么是Mycat为什么要用Mycatmycat能干什么各数据库中间件对比Mycat原理数据库中间件逻辑库逻辑表分片表分片规则全局表ER表非分片表分片节点节点主机mycat安装mycat核心配置schema.xmlserver.xmlrule.xml加密明文密码(可选) MyCat读写分离垂直拆…

OpenCV中的图像处理3.11(10) OpenCV中的图像变换

目录 3.11 OpenCV中的图像变换3.11.1 傅里叶变换目标理论Numpy中的傅里叶变换OpenCV中的傅立叶变换DFT的性能优化为什么Laplacian是一个高通滤波器?其他资源 翻译及二次校对:cvtutorials.com 编辑者:廿瓶鲸(和鲸社区Siby团队成员&…

2.3 YARN伪分布式集群搭建

任务目的 重点掌握 YARN 集群的相关配置学会启动和关闭 YARN 集群的两种方式能够使用 jps 命令查看进程的启动情况能够通过 UI 查看 YARN 集群的运行状态任务清单 任务1:YARN 集群主要配置文件讲解任务2:YARN 集群测试任务步骤 任务1:YARN 集群主要配置文件讲解 1.1 配置环…

基于多尺度图神经网络的流场预测,实现精度与速度的平衡

项目简介 本项目来源于飞桨AI for Science共创计划的论文复现赛题,复现论文为《AMGNET: multi-scale graph neural networks for flow field prediction》。该论文主要采用图神经网络,因为在计算流体力学中计算域被网格离散化,这与图结构天然…

将PDF1页分割为4页

运行效果 原始PDF 分割后PDF 一、python代码(用的是python3.9.0版本) import os import tempfile from pdf2image import convert_from_path from PIL import Image from PyPDF2 import PdfReader, PdfWriterdef split_pdf_page(pdf_path, output_path…

4G开发板-安卓手机开发套件-MTK主板开发板定制

开发板是一种用于嵌入式系统开发的电路板,它包含了各种硬件组件,如中央处理器、存储器、输入设备、输出设备、数据通路/总线以及外部资源接口等。为了满足特定的开发需求,嵌入式系统开发者通常会根据项目要求来定制开发板,当然用户…

2023年前端面试高频考点ES6

目录 ES6新增 数据类型 基本数据类型 引用数据类型 Null,NaN,Undefined toString,valueOf ,,Object.is() 判断数据类型:typeof运算符,instance of运算符,isPrototypeOf() 方…

数据分析第11课pandas时间序列(上+下)-第12期15,16课

数据分析思维:有逻辑性, 课前练习1 各大平台相继推出和迭代付费会员策略,如优酷会员、京东PLUS会员、网易云音乐黑胶VIP等,通过提供丰富的权益吸引用户成为付 费会员,提升用户黏性和忠诚度。请围绕付费会员回答以下问题: 以网易云音乐黑胶VIP为例,运营同学希望推出活动…

k8s 使用helm安装longhorn存储控制器

1.安装helm 参考:k8s helm安装使用_Apex Predator的博客-CSDN博客 2.配置基础环境 安装longhorn存储控制器需要用到iSCSI工具,所以需要在k8s所有节点上安装 yum -y install iscsi-initiator-utils 3.安装longhorn 3.1配置helm镜像源 helm repo ad…

kafka Ar 、ISR 、 OSR 已分配副本 同步中副本 、不同步副本 Controller 执行leader 重新分配

目录 Ar 、ISR 、 OSR 已分配副本 同步中副本 、不同步副本 Controller 执行leader 重新分配 Ar 、ISR 、 OSR 已分配副本 同步中副本 、不同步副本 AR分区所有已分配副本 ISR 在同步中的副本OSR 不同步副本 如果有一个节点挂掉,分区领导会渠道其他地方当上领导…

Git的理解以及在IDEA中的使用

什么是版本控制 版本控制是指记录一段时间内对一个文件或一组文件的更改的系统,称为“版本”。换句话说,这些版本将帮助您跟踪代码/项目中的更改,如果需要,还可以撤消这些更改。 当处理较大的项目时,这种能够比较、区…

“RAID0 vs RAID1 vs RAID5 vs RAID6 vs RAID10:哪种RAID级别最适合你的需求?“

概要: RAID(Redundant Array of Independent Disks)是一种数据存储技术,可以将多个硬盘组合起来以提高性能、可靠性和容错能力。下面是几种常见的RAID级别,以及它们的用途和特点。 目录 RAID 0RAID 1RAID 5RAID 6RAID…