好吧,所以把我的代码分解成块,我在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)
}