更新状态中的对象

状态可以保存任何类型的 JavaScript 值,包括对象。但您不应直接更改 React 状态中保存的对象。相反,当您想要更新对象时,您需要创建一个新对象(或复制现有对象),然后设置状态以使用该副本

将状态视为只读

将放入状态的任何 JavaScript 对象视为只读。

const [position, setPosition] = useState({ x: 0, y: 0 });

以下这段代码是无效的

onPointerMove={e => {
  position.x = e.clientX;
  position.y = e.clientY;
}}

替换为

onPointerMove={e => {
  setPosition({
    x: e.clientX,
    y: e.clientY
  });
}}

使用扩展语法复制对象

您可以使用... 对象扩展语法,这样就不需要单独复制每个属性。

setPerson({
  ...person, // Copy the old fields
  firstName: e.target.value // But override this one
});

...扩展语法是“浅层”的——它只复制一层。这使得它速度很快,但这也意味着如果你想更新嵌套属性,你必须多次使用它。

对多个字段使用单个事件处理程序

这里,e.target.name指的name是赋予 input DOM元素的属性。

  function handleChange(e) {
    setPerson({
      ...person,
      [e.target.name]: e.target.value
    });
  }

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

Immer是一个流行的库,它允许您使用方便但可变的语法编写,并负责为您生成副本。

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

Immer draft提供的是一种特殊类型的对象,称为Proxy,它“记录”了你对它所做的操作。这就是为什么你可以随心所欲地随意改变它!在底层,Immer 会找出哪些部分draft已被更改,并生成一个包含你编辑内容的全新对象。

使用 Immer

  • npm install -save
  • 然后替换 import { useState } from 'react'import { useImmer } from 'use-immer'
posted @ 2024-10-28 17:08  暖暖De幸福  阅读(3)  评论(0编辑  收藏  举报