状态值未在表单验证时更新



好吧,所以把我的代码分解成块,我在HTML中有以下内容:

<input
type="text"
name="email"
id="email"
autoComplete="email"
onChange={(e) => {validateField(e.target)}}
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
/>
<FormFieldError
Field='email'
FormFieldErrors={formFieldErrors}
/>

validateField函数如下所示:

const validateField = (field) => {
// console.log('validatefield', field.id, field.value)
switch(field.id) {
case 'email':
const pattern = /[a-zA-Z0-9]+[.]?([a-zA-Z0-9]+)?[@][a-z]{3,9}[.][a-z]{2,5}/g
const result = pattern.test(field.value)
if (result !== true) {
setFormFieldErrors({...formFieldErrors, email: 'Please enter a valid email address'})
console.log('Please enter a valid email address')
} else {
setFormFieldErrors({...formFieldErrors, email: null})
}
break
}

}

FormFieldError函数如下所示:

function FormFieldError({ Field, FormFieldErrors }) {
let message = FormFieldErrors[Field] ? FormFieldErrors[Field] : null
return (
<>
<div className="text-red-500 text-xs text-bold">{(message)}</div>
</>
)

}

现在,当在表单的onSubmit中时,我得到了以下功能:

const submitNewRegistration = async (event) => {
event.preventDefault()
Array.prototype.forEach.call(event.target.elements, (element) => {
validateField(element);
})
let errors = Object.keys(formFieldErrors).some(key => key !== null)
console.log(errors)
}

我在我的状态下声明formFieldErrors,如下所示:const [formFieldErrors, setFormFieldErrors] = useState({})

当我更改字段时,onChange函数对每个输入都非常有效,如果输入错误,则会显示输入下方的消息。FieldErrors会在输入下方显示消息。但是,当我从submitNewRegistration函数调用validateInput时,似乎不会调用setFormFieldErrors。事实上,即使我把setFormFieldErrors放在submitNewRegistration中,它似乎也不会改变formFieldErrors的状态。因此,当我试图在提交之前验证表单时,我不会收到任何错误。

有人能向我解释一下为什么它使用onChange方法,现在我从submitNewRegistration调用它吗??

并不是没有调用setFormFieldErrors,问题是您试图在状态更新之前依赖状态值。当您调用setState时,状态不会立即更新。这是因为setState是异步的,本质上是一个在组件的下一次呈现时解析的promise。

因此,要解决这个问题,您需要将验证逻辑剥离到状态更新之外。换句话说:

const validateField = (field) => {
// console.log('validatefield', field.id, field.value)
switch(field.id) {
case 'email':
const pattern = /[a-zA-Z0-9]+[.]?([a-zA-Z0-9]+)?[@][a-z]{3,9}[.][a-z]{2,5}/g
const result = pattern.test(field.value)
if (result !== true) {
return {email: 'Please enter a valid email address'}
console.log('Please enter a valid email address')
} else {
return {email: null}
}
break

}

然后在你的html:

<input
type="text"
name="email"
id="email"
autoComplete="email"
onChange={(e) => {
setFormFieldErrors({...formFieldErrors, ...validateField(e.target)})
}
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
/>
<FormFieldError
Field='email'
FormFieldErrors={formFieldErrors}
/>

最后提交:

const submitNewRegistration = async (event) => {
event.preventDefault()
let formErrors = formFieldErrors;;
Array.prototype.forEach.call(event.target.elements, (element) => {
formErrors = {...formErrors, ...validateField(element)};
})
setFormFieldErrors(formErrors)
let errors = Object.keys(formErrors).some(key => key !== null)
console.log(errors)
}

最新更新