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

Immer编写更简单的逻辑

Immer

当我们在更新一个复杂的嵌套对象时:

const [person, setPerson] = useState({
  name: 'Niki de Saint Phalle',
  artwork: {
    title: 'Blue Nana',
    city: 'Hamburg',    
    image: 'https://i.imgur.com/Sd1AgUOm.jpg',
  }
});

如果想要更新person.artwork.city的值,可以使用函数调用:

setPerson({
  ...person, // 复制其它字段的数据 
  artwork: { // 替换 artwork 字段 
    ...person.artwork, // 复制之前 person.artwork 中的数据
    city: 'New Delhi'  // 将 city 的值替换为 New Delhi!
  }
});

使用 Immer 编写简洁的更新逻辑

如果你的 state 有多层的嵌套,你或许应该考虑 将其扁平化。但是,如果你不想改变 state 的数据结构,你可能更喜欢用一种更便捷的方式来实现嵌套展开的效果。Immer 是一个非常流行的库,它可以让你使用简便但可以直接修改的语法编写代码,并会帮你处理好复制的过程。通过使用 Immer,你写出的代码看起来就像是你“打破了规则”而直接修改了对象:

updatePerson(draft => {
  draft.artwork.city = 'Lagos';
});

尝试使用 Immer:

  1. 运行 npm install use-immer 添加 Immer 依赖

  2. import { useImmer } from 'use-immer' 替换掉 import { useState } from 'react'

import { useImmer } from 'use-immer';

export default function Form() {
  const [person, updatePerson] = useImmer({
    name: 'Niki de Saint Phalle',
    artwork: {
      title: 'Blue Nana',
      city: 'Hamburg',
      image: 'https://i.imgur.com/Sd1AgUOm.jpg',
    }
  });

  function handleNameChange(e) {
    updatePerson(draft => {
      draft.name = e.target.value;
    });
  }

  function handleTitleChange(e) {
    updatePerson(draft => {
      draft.artwork.title = e.target.value;
    });
  }

  function handleCityChange(e) {
    updatePerson(draft => {
      draft.artwork.city = e.target.value;
    });
  }

  function handleImageChange(e) {
    updatePerson(draft => {
      draft.artwork.image = e.target.value;
    });
  }

  return (
    <>
      <label>
        Name:
        <input
          value={person.name}
          onChange={handleNameChange}
        />
      </label>
      <label>
        Title:
        <input
          value={person.artwork.title}
          onChange={handleTitleChange}
        />
      </label>
      <label>
        City:
        <input
          value={person.artwork.city}
          onChange={handleCityChange}
        />
      </label>
      <label>
        Image:
        <input
          value={person.artwork.image}
          onChange={handleImageChange}
        />
      </label>
      <p>
        <i>{person.artwork.title}</i>
        {' by '}
        {person.name}
        <br />
        (located in {person.artwork.city})
      </p>
      <img 
        src={person.artwork.image} 
        alt={person.artwork.title}
      />
    </>
  );
}

http://www.kler.cn/a/444847.html

相关文章:

  • SpringBoot3+Vue3开发在线考试系统
  • 说说你对 css3 display:flex 弹性盒模型 的理解
  • 阿里云 ECS 实例上升级 Docker 并使用多阶段构建
  • STM8单片机学习笔记·GPIO的片上外设寄存器
  • 轻松拿捏Spring
  • Arcgis for javascript 开发学习经验
  • 相机主要调试参数
  • LDO输入电压不满足最小压差时输出会怎样?
  • uboot, s5pv210, 内存讲解(3)
  • 【Nginx-4】Nginx负载均衡策略详解
  • 在Windows下安装redis
  • Python知识分享第三十一天-Numpy和Pnadas入门
  • 林子雨-大数据课程实验报告(二)
  • 气象与旅游之间的关系,如果借助高精度预测提高旅游的质量
  • 安徽移动携手开源网安亮相2024中国国际车联网技术大会,共筑车联网安全新壁垒
  • 无人设备遥控器之通讯技术篇
  • 技术速递|.NET 9 简介
  • 计算机基础 试题
  • 【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
  • 划分WLAN的三种主要方法,基于WLAN,基于IP,基于端口