admin 管理员组文章数量: 1086019
I have a Form.js ponent which returns a form element. This form element contains a FormGroup ponent which takes props such as inputType, inputName, inputPlaceholder and in return renders an input field with a label. I am using react-hook-form for the validation of the input but I can't get it to work after extracting the input to a separate ponent. In my original code, I had my errors appear when the validation failed, but after extracting the label and input into their own ponent, this stopped working.
My original working code looks like this:
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import FormGroup from './FormGroup';
const Form = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = async (data) => {
console.log(data)
};
return (
<form className="form-container" onSubmit={handleSubmit(onSubmit)} autoComplete="off" noValidate>
<div className="form-group">
<label className="form-label" htmlFor="firstName">
<p>First Name</p>
<p className="input-error">{errors.firstName && errors.firstName.message}</p>
</label>
<input type="text" name="firstName" placeholder="First Name" {...register("firstName", { required: 'Required ' })} />
</div>
<div className="form-group">
<button type="submit">Submit</button>
</div>
</form>
);
}
export default Form
Then I changed it to:
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import FormGroup from './FormGroup';
const Form = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = async (data) => {
console.log(data)
};
return (
<form className="form-container" onSubmit={handleSubmit(onSubmit)} autoComplete="off" noValidate>
<FormGroup
inputType="text"
inputName="firstName"
inputPlaceholder="First Name">
</FormGroup>
<div className="form-group">
<button type="submit">Submit</button>
</div>
</form>
);
}
export default Form
And I extracted the label and input into:
import { useForm } from 'react-hook-form';
const FormGroup = (props) => {
const { register, formState: { errors } } = useForm();
return (
<div className="form-group">
<label className="form-label" htmlFor={props.inputName}>
<p>{ props.inputPlaceholder }</p>
<p className="input-error">{errors.firstName && errors.firstName.message}</p>
</label>
<input type={props.inputType} name={props.inputName} placeholder={props.inputPlaceholder} {...register(props.inputName, { required: true })} />
</div>
);
}
export default FormGroup
I have a Form.js ponent which returns a form element. This form element contains a FormGroup ponent which takes props such as inputType, inputName, inputPlaceholder and in return renders an input field with a label. I am using react-hook-form for the validation of the input but I can't get it to work after extracting the input to a separate ponent. In my original code, I had my errors appear when the validation failed, but after extracting the label and input into their own ponent, this stopped working.
My original working code looks like this:
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import FormGroup from './FormGroup';
const Form = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = async (data) => {
console.log(data)
};
return (
<form className="form-container" onSubmit={handleSubmit(onSubmit)} autoComplete="off" noValidate>
<div className="form-group">
<label className="form-label" htmlFor="firstName">
<p>First Name</p>
<p className="input-error">{errors.firstName && errors.firstName.message}</p>
</label>
<input type="text" name="firstName" placeholder="First Name" {...register("firstName", { required: 'Required ' })} />
</div>
<div className="form-group">
<button type="submit">Submit</button>
</div>
</form>
);
}
export default Form
Then I changed it to:
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import FormGroup from './FormGroup';
const Form = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = async (data) => {
console.log(data)
};
return (
<form className="form-container" onSubmit={handleSubmit(onSubmit)} autoComplete="off" noValidate>
<FormGroup
inputType="text"
inputName="firstName"
inputPlaceholder="First Name">
</FormGroup>
<div className="form-group">
<button type="submit">Submit</button>
</div>
</form>
);
}
export default Form
And I extracted the label and input into:
import { useForm } from 'react-hook-form';
const FormGroup = (props) => {
const { register, formState: { errors } } = useForm();
return (
<div className="form-group">
<label className="form-label" htmlFor={props.inputName}>
<p>{ props.inputPlaceholder }</p>
<p className="input-error">{errors.firstName && errors.firstName.message}</p>
</label>
<input type={props.inputType} name={props.inputName} placeholder={props.inputPlaceholder} {...register(props.inputName, { required: true })} />
</div>
);
}
export default FormGroup
Share
Improve this question
asked Apr 18, 2021 at 3:28
OnyxOnyx
5,78210 gold badges52 silver badges119 bronze badges
2 Answers
Reset to default 3The Problem
You have multiple instances of the useForm
hook.
Solution
Use the useForm
hook only on the Form
ponent and pass the errors
object and register
method as props to FormGroup
Form Component
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import FormGroup from './FormGroup';
const Form = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
const onSubmit = async (data) => {
console.log(data);
};
return (
<form
className="form-container"
onSubmit={handleSubmit(onSubmit)}
autoComplete="off"
noValidate
>
<FormGroup
inputType="text"
inputName="firstName"
inputPlaceholder="First Name"
register={register}
errors={errors}
></FormGroup>
<div className="form-group">
<button type="submit">Submit</button>
</div>
</form>
);
};
export default Form;
FormGroup Component
import { useForm } from 'react-hook-form';
const FormGroup = (props) => {
return (
<div className="form-group">
<label className="form-label" htmlFor={props.inputName}>
<p>{props.inputPlaceholder}</p>
<p className="input-error">
{props.errors.firstName && props.errors.firstName.message}
</p>
</label>
<input
type={props.inputType}
name={props.inputName}
placeholder={props.inputPlaceholder}
{...props.register(props.inputName, { required: true })}
/>
</div>
);
};
export default FormGroup;
The remended approach from the Documentation is as follows:
useFormContext This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would bee inconvenient to pass the context as a prop. https://react-hook-form./api/useformcontext
const Form = () => {
const methods = useForm();
const {
register,
handleSubmit,
formState: { errors },
} = methods;
const onSubmit = async (data) => {
console.log(data);
};
return (
<FormProvider {...methods} >
<form
className="form-container"
onSubmit={handleSubmit(onSubmit)}
autoComplete="off"
noValidate
>
<FormGroup
inputType="text"
inputName="firstName"
inputPlaceholder="First Name">
</FormGroup>
<div className="form-group">
<button type="submit">Submit</button>
</div>
</form>
</FormProvider>
);
};
const FormGroup = (props) => {
const { register, errors } = useFormContext(); // retrieve all hook methods from parent
return (
<div className="form-group">
<label className="form-label" htmlFor={props.inputName}>
<p>{props.inputPlaceholder}</p>
<p className="input-error">
{errors.firstName && errors.firstName.message}
</p>
</label>
<input
type={props.inputType}
name={props.inputName}
placeholder={props.inputPlaceholder}
{register(props.inputName, { required: true })}
/>
</div>
);
};
export default FormGroup;
本文标签:
版权声明:本文标题:javascript - I'm using react-hook-form to validate my input but I can't get it to work after extracting the inpu 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744093000a2532383.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论