I am making a simple react form with a react-hook-form and yup as the validator. If the user's input is successfully validated, I want to show some feedback to the user, like a green outline. The problem is that I only want to show the green outline when my input has been validated, not every time the component is rendered. How can I do this? Component:
const schema = yup.object().shape({
email: yup
.string()
.required("This field is required"),
password: yup.string().required("This field is required"),
});
export const Form = () => {
const {
register,
handleSubmit,
getValues,
formState: { errors },
} = useForm({
mode: "onBlur",
resolver: yupResolver(schema),
});
return (
<form noValidate onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="email">Email</label>
<input
id="email"
{...register("email")}
/>
{errors.email ? errors?.email.message : null}
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
{...register("password")}
/>
{errors.password ? errors?.password.message : null}
<button
type="submit"
>
Submit
</button>
</form>
);
};
CodePudding user response:
You can implement what you want with the touched property. Using the touched property for this kind of scenario is very common. Here's what you can do:
From the useForm
hook, you can also extract the touchedFields
const {
register,
handleSubmit,
getValues,
formState: { errors, touchedFields }
} = useForm({
mode: "onBlur",
resolver: yupResolver(schema)
});
The touchedFields properties stores the touched fields. A field is touched the first time the user leaves the focus from that field. So, then you can conditionally show a message about a field if it is touched and it has no errors like this:
{touchedFields.email && !errors.email ? <div>Email ok</div> : null}
You can try this sandbox. I hope you can get the idea from it.