带有挂钩的功能组件中的数组未在 React State 中更新
Array not updating in React State in a function component with hooks
我正在探索表单验证并在 State 中有一个 validationMessages 数组来存储验证消息。当用户提交表单时,我 运行 验证并尝试更新 State 中的 validationMessages 数组。但是只添加了最后一个 validationMessage 而没有添加前面的。代码如下:
import React, { useState } from 'react';
function Form(props) {
const [validationMessages, setValidationMessages] = useState([]);
const [formData, setFormData] = useState({});
const handleChange = ({ target }) => {
setFormData({ ...formData, [target.name]: target.value });
}
const handleClick = (evt) => {
validateForm();
if (validationMessages.length > 0) {
evt.preventDefault();
}
}
const validateForm = () => {
const { firstName, lastName, DOB, gender } = formData;
setValidationMessages([]);
if (!firstName) {
setValidationMessages([...validationMessages, "First Name is required"]);
}
if (!lastName) {
setValidationMessages([...validationMessages, "Last Name is required"]);
}
if (!gender) {
setValidationMessages([...validationMessages, "Please select a Gender"]);
}
if (!DOB) {
setValidationMessages([...validationMessages, "Date of Birth is required"]);
}
}
return <div style={{ display: 'flex', flexDirection: 'row' }} >
<form style={{ display: 'flex', flexDirection: 'column' }}>
<label>First Name</label>
<input value={formData.firstName || ''} onChange={handleChange} type="text" name="firstName" />
<label>Last Name</label>
<input value={formData.lastName || ''} onChange={handleChange} type="text" name="lastName" />
<label>Date of Birth</label>
<input value={formData.DOB || ''} onChange={handleChange} type="datetime-local" name="DOB" />
<label>Gender</label>
<div><input value="Male" checked={formData.gender === "Male"} onChange={handleChange} type="radio" name="gender" />Male</div>
<div><input value="Female" checked={formData.gender === "Female"} onChange={handleChange} type="radio" name="gender" />Female</div>
<div><input value="None" checked={formData.gender === "None"} onChange={handleChange} type="radio" name="gender" />Prefer not to say</div>
<button type="button" onClick={handleClick}>Save</button>
</form><div>{validationMessages.length > 0 && <span>Validation Summary</span>}
<ul>
{validationMessages.map(vm => <li key={vm}>{vm}</li>)}
</ul></div></div>;
}
export default Form;
问题是,如果我将所有字段留空,那么仍然只有最后一条验证消息被添加到 validationMessages 的状态数组中。即使在 whosebug.com 上花了相当多的时间查看类似问题及其答案后也无法弄清楚。感谢任何指点或帮助。
在您的 validateForm
中,您多次调用 setValidationMessages
以将消息添加到状态数组。但是 setValidationMessages
是异步的,所以第二次调用不会有新版本的 validationMessages
因此只有最后一条消息会被保存到 state
这是一个可能的解决方案:
const validateForm = () => {
const { firstName, lastName, DOB, gender } = formData;
const messages = [];
if (!firstName) {
messages.push("First Name is required");
}
if (!lastName) {
messages.push"Last Name is required");
}
if (!gender) {
messages.push("Please select a Gender");
}
if (!DOB) {
messages.push("Date of Birth is required");
}
setValidationMessages(messages);
}
我正在探索表单验证并在 State 中有一个 validationMessages 数组来存储验证消息。当用户提交表单时,我 运行 验证并尝试更新 State 中的 validationMessages 数组。但是只添加了最后一个 validationMessage 而没有添加前面的。代码如下:
import React, { useState } from 'react';
function Form(props) {
const [validationMessages, setValidationMessages] = useState([]);
const [formData, setFormData] = useState({});
const handleChange = ({ target }) => {
setFormData({ ...formData, [target.name]: target.value });
}
const handleClick = (evt) => {
validateForm();
if (validationMessages.length > 0) {
evt.preventDefault();
}
}
const validateForm = () => {
const { firstName, lastName, DOB, gender } = formData;
setValidationMessages([]);
if (!firstName) {
setValidationMessages([...validationMessages, "First Name is required"]);
}
if (!lastName) {
setValidationMessages([...validationMessages, "Last Name is required"]);
}
if (!gender) {
setValidationMessages([...validationMessages, "Please select a Gender"]);
}
if (!DOB) {
setValidationMessages([...validationMessages, "Date of Birth is required"]);
}
}
return <div style={{ display: 'flex', flexDirection: 'row' }} >
<form style={{ display: 'flex', flexDirection: 'column' }}>
<label>First Name</label>
<input value={formData.firstName || ''} onChange={handleChange} type="text" name="firstName" />
<label>Last Name</label>
<input value={formData.lastName || ''} onChange={handleChange} type="text" name="lastName" />
<label>Date of Birth</label>
<input value={formData.DOB || ''} onChange={handleChange} type="datetime-local" name="DOB" />
<label>Gender</label>
<div><input value="Male" checked={formData.gender === "Male"} onChange={handleChange} type="radio" name="gender" />Male</div>
<div><input value="Female" checked={formData.gender === "Female"} onChange={handleChange} type="radio" name="gender" />Female</div>
<div><input value="None" checked={formData.gender === "None"} onChange={handleChange} type="radio" name="gender" />Prefer not to say</div>
<button type="button" onClick={handleClick}>Save</button>
</form><div>{validationMessages.length > 0 && <span>Validation Summary</span>}
<ul>
{validationMessages.map(vm => <li key={vm}>{vm}</li>)}
</ul></div></div>;
}
export default Form;
问题是,如果我将所有字段留空,那么仍然只有最后一条验证消息被添加到 validationMessages 的状态数组中。即使在 whosebug.com 上花了相当多的时间查看类似问题及其答案后也无法弄清楚。感谢任何指点或帮助。
在您的 validateForm
中,您多次调用 setValidationMessages
以将消息添加到状态数组。但是 setValidationMessages
是异步的,所以第二次调用不会有新版本的 validationMessages
因此只有最后一条消息会被保存到 state
这是一个可能的解决方案:
const validateForm = () => {
const { firstName, lastName, DOB, gender } = formData;
const messages = [];
if (!firstName) {
messages.push("First Name is required");
}
if (!lastName) {
messages.push"Last Name is required");
}
if (!gender) {
messages.push("Please select a Gender");
}
if (!DOB) {
messages.push("Date of Birth is required");
}
setValidationMessages(messages);
}