我正在使用 react-hook-form 来验证我的输入,但是在将输入提取到它自己的组件后我无法让它工作
I'm using react-hook-form to validate my input but I can't get it to work after extracting the input to its own component
我有一个 Form.js 组件,它 return 是一个表单元素。此表单元素包含一个 FormGroup 组件,该组件采用 inputType、inputName、inputPlaceholder 等道具,并在 return 中呈现带有标签的输入字段。我正在使用 react-hook-form 来验证输入,但在将输入提取到单独的组件后我无法让它工作。在我的原始代码中,我在验证失败时出现错误,但是在提取标签并输入到他们自己的组件中后,它停止工作了。
我原来的工作代码是这样的:
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
然后我改成了:
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
然后我提取标签并输入到:
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
问题
您有多个 useForm
挂钩实例。
解决方案
仅在 Form
组件上使用 useForm
挂钩,并将 errors
对象和 register
方法作为 props 传递给 FormGroup
表单组件
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 组件
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;
文档中推荐的方法如下:
useFormContext This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop.
https://react-hook-form.com/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;
我有一个 Form.js 组件,它 return 是一个表单元素。此表单元素包含一个 FormGroup 组件,该组件采用 inputType、inputName、inputPlaceholder 等道具,并在 return 中呈现带有标签的输入字段。我正在使用 react-hook-form 来验证输入,但在将输入提取到单独的组件后我无法让它工作。在我的原始代码中,我在验证失败时出现错误,但是在提取标签并输入到他们自己的组件中后,它停止工作了。
我原来的工作代码是这样的:
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
然后我改成了:
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
然后我提取标签并输入到:
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
问题
您有多个 useForm
挂钩实例。
解决方案
仅在 Form
组件上使用 useForm
挂钩,并将 errors
对象和 register
方法作为 props 传递给 FormGroup
表单组件
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 组件
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;
文档中推荐的方法如下:
useFormContext This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. https://react-hook-form.com/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;