You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 09:45:46