更新状态中的对象
状态可以保存任何类型的 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'