如何用React Hook与Yup构建带校验的可复用输入组件及解决Register传参问题?
构建带校验的可复用React Hook Form输入组件
核心修正方案
你无法传递register相关属性的问题,主要是因为自定义Input组件缺少正确的类型定义,或是没有正确传递register返回的绑定属性。以下是修正后的完整代码实现:
1. 自定义Input组件(components/input.tsx)
import React from 'react'; // 整合原生Input属性与自定义的label、错误提示属性 type InputProps = React.InputHTMLAttributes<HTMLInputElement> & { label: string; error?: string; }; export default function Input({ label, error, ...rest }: InputProps) { return ( <div style={{ marginBottom: '1rem' }}> <label htmlFor={rest.name} style={{ display: 'block', marginBottom: '0.5rem' }}> {label} </label> <input {...rest} style={{ padding: '0.5rem', border: error ? '1px solid #ef4444' : '1px solid #d1d5db', borderRadius: '4px', width: '100%' }} /> {error && <p style={{ color: '#ef4444', marginTop: '0.25rem', margin: 0 }}>{error}</p>} </div> ); }
2. 父组件使用示例(pages/index.tsx)
import { useForm } from 'react-hook-form'; import Input from '../components/input'; // 定义表单数据类型,替代any提升类型安全 type FormData = { username: string; email: string; }; export default function Home() { const { register, handleSubmit, formState: { errors } } = useForm<FormData>(); const onSubmit = (data: FormData) => { console.log('表单数据:', data); // 这里可添加提交逻辑 }; return ( <div style={{ maxWidth: '400px', margin: '2rem auto', padding: '0 1rem' }}> <form onSubmit={handleSubmit(onSubmit)}> <Input label="用户名" {...register('username', { required: '用户名不能为空', minLength: { value: 3, message: '用户名至少需要3个字符' } })} error={errors.username?.message} /> <Input label="邮箱" type="email" {...register('email', { required: '邮箱不能为空', pattern: { value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, message: '请输入有效的邮箱地址' } })} error={errors.email?.message} /> <button type="submit" style={{ padding: '0.5rem 1rem', backgroundColor: '#3b82f6', color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer' }} > 提交 </button> </form> </div> ); }
关键说明
- 类型安全:通过
React.InputHTMLAttributes<HTMLInputElement>让Input组件支持所有原生input属性,避免传递register返回值时出现类型错误。 - 校验逻辑:在父组件调用
register时传入校验规则,通过formState.errors获取错误信息并传递给Input组件展示。 - 可复用性:Input组件封装了label、输入框、错误提示的样式和结构,只需传入不同的label、校验规则和错误信息即可重复使用。
内容的提问来源于stack exchange,提问作者robokonk
相关产品推荐
相关产品推荐

