【发布时间】:2021-04-01 08:22:21
【问题描述】:
我的表单运行良好,但我需要立即进行验证(一旦用户散焦该字段,我希望仅显示该字段的错误消息)。目前我有一个验证,当单击提交按钮时显示错误消息:
代码如下:
- useForm 挂钩
import { useState, useEffect } from 'react';
const useForm = (callback, validate, post) => {
const [values, setValues] = useState(post || {});
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
useEffect(() => {
if (Object.keys(errors).length === 0 && isSubmitting) {
callback();
}
}, [errors]);
const handleSubmit = (event) => {
if (event) event.preventDefault();
console.log('values in useForm', values)
setErrors(validate(values))
setIsSubmitting(true);
};
const handleInputChange = (event) => {
event.persist();
setValues(values => ({ ...values, [event.target.name]: event.target.value }));
};
return {
handleInputChange,
handleSubmit,
values,
errors,
}
};
export default useForm;
- 验证函数
const validate = (values) => {
const errors = {};
if (!values.title) {
errors.title = 'Title is required'
} else if (values.title.length < 5) {
errors.title = 'Title must be at least 5 characters long'
}
if (!values.body) {
errors.body = "Blog body is required"
} else if (values.body.length < 2 || values.body.length > 20) {
errors.body = "Text has to be between 2 and 20 characters long"
}
if (!values.author) {
errors.author = "The author's name is required"
}
if (!values.number) {
errors.number = "A number is required"
}
if (!values.email) {
errors.email = 'Email is required';
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
return errors;
}
export default validate;
- 表单组件
import { useHistory } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import useForm from '../hooks/useForm';
import { addPost } from '../actions';
import validate from '../helpers/validate';
const CreateForm = () => {
const dispatch = useDispatch();
const history = useHistory();
const { values, handleInputChange, handleSubmit, errors } = useForm(submit, validate)
const { title, body, author, number, email } = values;
function submit() {
console.log("No errors", values)
const post = values;
console.log('Submit form', post)
dispatch(addPost(post))
history.push('/');
}
return (
<div className="create">
<h2>Add a new blog</h2>
<form onSubmit={handleSubmit} noValidate>
<label>Blog title:</label>
<input
type="text"
required
name="title"
value={title || ""}
onChange={handleInputChange}
className={errors.title ? 'red-border' : ""}
/>
{errors.title && (<p className="danger">{errors.title}</p>)}
<label>Blog body:</label>
<textarea
required
name="body"
value={body || ""}
onChange={handleInputChange}
className={errors.body ? 'red-border' : ""}
/>
{errors.body && (
<p className="danger">{errors.body}</p>
)}
<label>Author:</label>
<input
type="text"
required
name="author"
value={author || ""}
onChange={handleInputChange}
className={errors.author ? 'red-border' : ""}
/>
{errors.author && (
<p className="danger">{errors.author}</p>
)}
<label>Number:</label>
<input
type="number"
required
name="number"
value={number || ""}
onChange={handleInputChange}
className={errors.number ? 'red-border' : ""}
/>
{errors.number && (
<p className="danger">{errors.number}</p>
)}
<label>Email:</label>
<input
type="text"
required
name="email"
value={email || ""}
onChange={handleInputChange}
className={errors.email ? 'red-border' : ""}
/>
{errors.email && (
<p className="danger">{errors.email}</p>
)}
<button>Save</button>
</form>
</div>
);
}
export default CreateForm;
【问题讨论】:
-
只需在handleInputChange 中调用setErrors,而不是在handleSubmit 中调用。如果我正确理解了您的问题,那就是它的全部内容
-
不行,我试过了。
-
您需要告诉我们您尝试了什么以及您的意思是什么不起作用:您遇到了哪个错误等。无论如何,请稍等,我会给您一个简单的示例代码沙盒
-
我就是这么做的,我在 useForm 挂钩中创建了一个新函数 validateInput,我在其中调用了 setErrors。 const validateInput = (e) => {setErrors(validate(e.target.value))}。然后我在每个输入字段 onBlur={validateInput} 上调用 valideteInput。我在控制台中没有收到任何错误,但是当我散焦一个字段时,我会得到所有字段的所有错误,而不仅仅是散焦字段。我认为问题出在 validate 函数中,因为它适用于所有值,但我不确定。
-
我相信你说对了一半:你的 validate 函数会生成一个错误对象,然后你用 setErrors 覆盖它而不传播状态。查看答案中的代码框以了解如何解决您的问题: setErrors({...errors, []})
标签: javascript reactjs forms validation redux