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

React Hook Form动态字段的Yup验证问题求助

React Hook Form 动态字段结合Yup验证解决方案

你的代码核心问题是Yup Schema未针对动态生成的childrenNames数组配置验证规则,同时存在几处React Hook Form的使用细节错误,以下是完整修正方案:

修正后的父组件代码

import { useFieldArray, useForm } from 'react-hook-form';
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { useCallback, useMemo } from 'react';
import { Row, Col } from '你的UI库路径'; // 替换为实际UI库路径
import Input from './Input'; // 替换为实际子组件路径

// 完善Yup验证规则,新增childrenNames数组验证
const schema = yup.object().shape({
  name: yup.string().required('姓名不能为空'),
  surname: yup.string().required('姓氏不能为空'),
  // 验证数组中每个子项的childrenName字段必填
  childrenNames: yup.array().of(
    yup.object().shape({
      childrenName: yup.string().required('孩子姓名不能为空')
    })
  )
});

const PersonalInformation = () => {
  // 解构出control,useFieldArray必须依赖它
  const { handleSubmit, register, control, formState: { errors } } = useForm({
    resolver: yupResolver(schema),
    defaultValues: {
      name: '', // 补充name和surname的默认值
      surname: '',
      childrenNames: [{ childrenName: '' }],
    },
  });

  // useCallback添加正确依赖,避免闭包问题
  const handleAppend = useCallback(() => append({ childrenName: '' }), [append]);
  const removeFields = useCallback((index) => remove(index), [remove]);

  const { append, remove, fields } = useFieldArray({
    control,
    name: 'childrenNames',
  });

  // useMemo补充register到依赖,符合Hook规则
  const nameInput = useMemo(
    () => <Input 
      id="name" 
      inputName="你的姓名" 
      register={register} 
      name="name" 
      error={errors?.name?.message} 
      required 
    />,
    [errors?.name, register],
  );

  const surNameInput = useMemo(
    () => <Input 
      id="surname" 
      inputName="你的姓氏" 
      register={register} 
      name="surname" 
      error={errors?.surname?.message} 
      required 
    />,
    [errors?.surname, register], // 修复原代码缺少的逗号
  );

  // 表单提交逻辑
  const onSubmit = (data) => {
    console.log('表单数据:', data);
    // 此处添加你的提交逻辑
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Row>
        <Col xs={4}>{nameInput}</Col>
        <Col xs={4}>{surNameInput}</Col>
      </Row>
      {fields?.map((field, index) => (
        <Row key={field?.id} className="mt-5">    
          <Col xs={4}>
            <Input
              inputName="孩子姓名"
              name={`childrenNames[${index}].childrenName`}
              register={register}
              error={errors?.childrenNames?.[index]?.childrenName?.message}
              id={`childrenName-${index}`} // 给动态字段设置唯一id
              required
            />
          </Col>
        
          <div className="final-buttons">
            <div className="btn-start">
              <button onClick={handleAppend} type="button">
                + 添加
              </button>
            </div>
            {/* 至少保留一个孩子字段,可根据需求调整 */}
            {fields.length > 1 ? (
              <div>
                <button type="button" onClick={() => removeFields(index)}>删除</button>
              </div>
            ) : null}
          </div>
        </Row>
      ))}
      {/* 补充提交按钮 */}
      <button type="submit" className="mt-3">提交</button>
    </form>
  );
};

export default PersonalInformation;

修正后的子组件代码

const Input = ({ error, inputName, id, register, type = 'text', name, placeholder, required }) => {
  return (
    <div className="form-input">
      <label htmlFor={id}>
        {inputName}
        {required && <span className="text-red-500 ml-1">*</span>}
      </label>
      {/* 修复原代码的inputType错误,改为props传入的type */}
      <input 
        type={type} 
        {...register(name)} 
        id={id} 
        placeholder={placeholder} 
        className={`${error ? 'error-status' : ''}`} 
      />
      {/* 显示错误提示 */}
      {error && <p className="text-red-500 text-sm mt-1">{error}</p>}
    </div>
  );
};

export default Input;

关键改动说明

  1. Yup规则完善:新增childrenNames数组验证,确保每个动态添加的孩子姓名字段非空。
  2. Hook依赖修正:useCallback添加append/remove依赖,useMemo补充register依赖,避免闭包导致的状态异常。
  3. 错误信息传递:给动态字段的Input组件传递对应索引的错误信息,让错误提示正常渲染。
  4. 细节修复:补充表单默认值、修复子组件inputType参数错误、添加提交按钮、给动态字段设置唯一id等。

内容的提问来源于stack exchange,提问作者Rahil Əliyev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:24:55