![](/img/trans.png)
[英]How to update a single property in a React state (function component)
[英]React: Cannot update object property in state in function component
我试图解决的问题:对一个内置 React 的应用程序进行表单验证,该应用程序接受用户输入并生成 CV。 这是为了学习目的,也是奥丁计划课程的一部分。
我是如何尝试解决表单验证问题的:我在 App.js 中使用大型 formData object 设置为 state 来组织我的项目,并且我通过 useContext 将 state 共享给所有子组件。 为了验证,我在我的 formData object 中为每条 CV 数据提供了 2 个属性。示例如下:
{firstname: '', firstNameValid: true}
我正在尝试编写一个 function(请参阅附加代码)来设置每个 propertyValid 的有效性并将其设置为 false。
我的期望:当一个字段无效(如 firstName)时,它会在我运行invalidateField('firstName')
function 时设置firstNameValid: false
。
相反会发生什么:记录 formData 显示firstNameValid
仍设置为true
。
我尝试了什么:如附加代码所示,我正在尝试复制我的 formData object,仅设置我想要的值,然后使用setFormData(formCopy)
手动设置它。 但是,当我将它们记录在一起时,我看到虽然 formCopy 看起来像我想要的那样,但 state 中的 formData 仍然没有改变。 我正在从我的孙子组件更新 state,但我无法在此处执行此操作,我不明白为什么。
//my object declared in state
const [formData, setFormData] = React.useState({
firstName: '',
lastName: '',
email: '',
firstNameValid: true,
lastNameValid: true,
emailValid: true
//a lot more than this but you get the idea
});
//function in question that is not working
function invalidateField(string){
//takes the name of the key as a string
let key = `${string}Valid`;
let value = false;
let formCopy = {...formData};
formCopy[key] = value;
setFormData(formCopy);
console.log(formCopy, formData);
}
//function I'm writing to check validity of input fields
//called by button click elsewhere in code
function formIsValid(formData){
let validity = true;
if(formData.firstName.length < 1){ //firstName = '' (field is empty)
console.log('your first name is too short');
invalidateField('firstName');
validity = false;
}
return validity;
}
//context then passed to child components in the return statement.
setFormData 方法是一个异步的 function。需要一段时间才能更新 state。 您在调用 setFormData 后立即使用 console.log,这就是为什么它看起来好像您的 setState 没有正常工作,只是需要更多时间才能完成。
在您的 invalidateField function 上方,您可以编写一个 useEffect 以在您的 state 发生更改时打印出来:
import { useEffect } from "react";
useEffect(() => {
console.log(formData);
}, [formData]);
这将在 formData 更改后立即执行 console.log。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.