我处于以下状态:
const [state, setState] = React.useState({
title: "",
exchangeTypes: [],
errors: {
title: "",
exchangeTypes: "",
}
})
如果不遵守条件,我正在使用表单验证来填充state.errors
对象。
function formValidation(e){
const { name, value } = e.target;
let errors = state.errors;
switch (true) {
case (name==='title' && value.length < 4):
setState(prevState => ({
errors: { // object that we want to update
...prevState.errors, // keep all other key-value pairs
[name]: 'Title cannot be empty' // update the value of specific key
}
}))
break;
default:
break;
}
}
这样做时,对象确实会更新,但是会删除我尚未更新的值。
在我调用formValidation之前
我的console.log(state)
是:
{
"title": "",
"exchangeTypes: [],
"errors": {
title: "",
exchangeTypes: "",
}
}
我致电formValidation 之后
我的console.log(state)
是:
{
"errors": {
title: "Title cannot be empty",
exchangeTypes: ""
}
}
SO 我的其他state
值已消失。只有errors
对象。
我遵循了本指南:How to update nested state properties in React
我想要什么:
{
"title": "",
"exchangeTypes: [],
"errors": {
title: "Title cannot be empty",
exchangeTypes: "",
}
}
我得到的是
{
"errors": {
title: "Title cannot be empty",
exchangeTypes: "",
}
}
答案 0 :(得分:2)
与类组件中的setState不同,当您使用对象作为值时,通过useState的setState不会自动合并。您必须手动完成
setState((prevState) => ({
...prevState, // <- here
errors: {
// object that we want to update
...prevState.errors, // keep all other key-value pairs
[name]: 'Title cannot be empty', // update the value of specific key
},
}));
答案 1 :(得分:1)
尽管您当然可以按照自己的方式使用useState
钩子,但更常见的约定是分别跟踪组件状态的各个部分。这是因为const MyComponent = () => {
const [title, setTitle] = useState('');
const [exchangeTypes, setExchangeTypes] = useState([]);
const [errors, setErrors] = useState({
title: "",
exchangeTypes: "",
});
function formValidation(e) {
const { name, value } = e.target;
switch (true) {
case (name === 'title' && value.length < 4):
setErrors({
...errors,
[name]: 'Title cannot be empty'
});
break;
default:
break;
}
}
return (
...
);
};
取代了状态,而不是像您发现的那样将其合并。
来自React docs:
您不必使用很多状态变量。状态变量可以很好地容纳对象和数组,因此您仍然可以将相关数据分组在一起。但是,与类中的this.setState不同,更新状态变量总是替换它而不是合并它。
因此,实际上,您的代码可能如下所示:
type