您正在尝试根据之前的状态进行状态更新。基本上问题如下:
您希望同步进行少量状态更新(当少数属性无效时)并且仅应用最后一次更新。
那么为什么会这样呢?
在上面的代码中,当错误等于初始状态并且所有字段都为空时会发生以下情况
setErrors({
...errors,
name: 'Name cannot be empty',
});
与
相同
setErrors({
description: '',
price: '',
category: '',
image: '',
name: 'Name cannot be empty',
});
之后,您输入另一个 if 语句,并且您正在执行另一个具有相同状态的 setState 操作,并且错误数组消失了是相同的
所以这个
setErrors({
...errors,
category: 'Category cannot be empty',
});
会变成这个
setErrors({
description: '',
price: '',
category: 'Category cannot be empty',
image: '',
name: '',
});
React 将一个接一个地安排所有的 setState,当您分配对象时,它只会覆盖最后一个现有的,并且 name 属性将被清除。
因此,如果要将对象用作状态,有两种方法可以解决当前问题:
生成对象,然后使用组合对象执行一次 setState,其中包含所有更改:
const [errors, setErrors] = useState({
name: '',
description: '',
price: '',
category: '',
image: '',
});
const handleValidation = () => {
const newErrorsState = {...errors};
let formIsValid = true;
//Name
if(!formState.name){
formIsValid = false;
newErrorsState.name = 'Name cannot be empty';
}
//category
if(!formCategory.category){
formIsValid = false;
newErrorsState.category = 'Category cannot be empty';
}
//Image
if(!image.image){
formIsValid = false;
newErrorsState.image = 'Image cannot be empty';
}
if (!formIsValid) { // if any field is invalid - then we need to update our state
setFormIsValid(false);
setErrors(newErrorsState);
}
return formIsValid;
};
解决此问题的第二种方法是使用另一种方法来设置您的状态,
您可以在 setState 处理程序中使用函数。在该函数中,您将收到最新状态作为参数,并且该状态将具有最新更改。
更多信息可以通过link找到
const [errors, setErrors] = useState({
name: '',
description: '',
price: '',
category: '',
image: '',
});
const [formIsValid, setFormIsValid] = useState(true);
const handleValidation = () => {
//Name
if(!formState.name){
setFormIsValid(false);
const updateNameFunction = (latestState) => {
return {
...latestState,
name: 'Name cannot be empty',
};
}
setErrors(updateNameFunction);
}
//category
if(!formCategory.category){
setFormIsValid(false);
setErrors((prevErrors) => {
return {
...prevErrors,
category: 'Category cannot be empty',
}
});
}
//Image
if(!image.image){
setFormIsValid(false);
setErrors((prevErrors) => {
return {
...errors,
image: 'Image cannot be empty',
};
});
}
return formIsValid;
};