为什么状态只在最后一个 if en else 语句中更新。 仅
setFilledIn
中的年龄设置为 true
和 false
有人可以帮助我理解 React 中的状态吗? 因为我不知道我做错了什么。
顺便说一下,如果我注释掉最后一个 if 语句,那么 lastName 的 if 语句就可以工作。
const [filledIn, setFilledIn] = useState({
firstName: true,
lastName: true,
age: true,
});
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (firstNameRef.current == null || firstNameRef.current.value === "") {
setFilledIn({ ...filledIn, firstName: false });
} else {
setFilledIn({ ...filledIn, firstName: true });
person2.firstName = firstNameRef.current.value;
}
if (lastNameRef.current == null || lastNameRef.current.value == "") {
setFilledIn({ ...filledIn, lastName: false });
} else {
setFilledIn({ ...filledIn, lastName: true });
person2.lastName = lastNameRef.current.value;
}
if (ageRef.current == null || ageRef.current.value == "") {
setFilledIn({ ...filledIn, age: false });
} else {
setFilledIn({ ...filledIn, age: true });
person2.age = parseInt(ageRef.current.value);
}
};
filledIn
在组件重新渲染之前不会改变,这里对代码状态的每次更新都不会重新渲染组件,只有当所有代码都在handleSubmit
完成执行时才会发生。因此,由于我们仍然处于相同的渲染中,即使您更新 firstName
的 filledIn
,然后尝试以这种方式更新 lastName
:
setFilledIn({ ...filledIn, lastName: false });
filledIn
仍然保持相同的值,没有任何更新。setFilledIn((prev) => {
return {
...prev,
lastName: false,
};
});
使用
prev
,即使组件尚未重新渲染,您也可以访问状态的最后一个值,然后您返回的是您希望状态更新的值。 这实际上是更新状态的最佳方法,您希望它始终根据其先前的值而不是当前渲染期间的值进行更新,您遇到的情况就是一个很好的例子,说明了这种方法如何更好。
我还没有对此进行测试,因此它只能作为有根据的猜测。但我假设它与您每次调用 setState 时使用 spread 实用程序(...)的用户有关。从技术上讲,您不需要这些,因为您已经使用 useState 初始化了状态。但是,如果您想使用它们而不是初始化状态,那么您必须在密钥对中的名称空间周围放置 [] 。例如:
setFilledIn({ ...filledIn, [lastName]: false });
或
setFilledIn({ lastName: false });
问题是您要分别更新每个字段的状态,因此只有最后一个字段的更新才会反映在最终状态中。这是因为 setFilledIn 函数调用是异步的,每次调用都会覆盖之前的更新。
要解决此问题,您可以在检查所有字段后在函数结束时更新状态一次。
const [filledIn, setFilledIn] = useState({
firstName: true,
lastName: true,
age: true,
});
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
let updatedFilledIn = { ...filledIn };
if (firstNameRef.current == null || firstNameRef.current.value === "") {
updatedFilledIn.firstName = false;
} else {
updatedFilledIn.firstName = true;
}
if (lastNameRef.current == null || lastNameRef.current.value === "") {
updatedFilledIn.lastName = false;
} else {
updatedFilledIn.lastName = true;
}
if (ageRef.current == null || ageRef.current.value === "") {
updatedFilledIn.age = false;
} else {
updatedFilledIn.age = true;
}
setFilledIn(updatedFilledIn);
};
或者你可以将其简化为
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
let updatedFilledIn = { ...filledIn };
const fields = {
firstName: firstNameRef,
lastName: lastNameRef,
age: ageRef,
};
Object.entries(fields).forEach(([fieldName, fieldRef]) => {
if (fieldRef.current == null || fieldRef.current.value === "") {
updatedFilledIn[fieldName] = false;
} else {
updatedFilledIn[fieldName] = true;
}
});
setFilledIn(updatedFilledIn);
};