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

React Hook Form结合Yup动态创建输入框聚焦异常问题求解

解决React Hook Form动态字段添加后焦点跳转问题

要实现点击添加按钮后,焦点自动落在最后一个动态创建的输入框上,可通过ref数组追踪动态输入框并在字段更新后手动触发焦点,具体步骤如下:

1. 创建ref数组存储动态输入框引用

在组件内部定义一个ref数组,用于记录每个动态生成的配料名称输入框的DOM引用:

const ingredientRefs = useRef([]);

2. 绑定ref到动态输入框

在渲染动态配料字段的Controller组件中,将每个输入框的ref存入数组:

{watch("ingredients").map((_, index) => (
  <div key={index} className="flex gap-2 mb-2">
    <Controller
      name={`ingredients.${index}.name`}
      control={control}
      rules={{ required: true }}
      render={({ field }) => (
        <input
          {...field}
          // 将当前输入框的ref存入数组对应索引位置
          ref={(el) => {
            ingredientRefs.current[index] = el;
          }}
          type="text"
          placeholder="配料名称"
          className="border p-2 flex-1"
        />
      )}
    />
    <Controller
      name={`ingredients.${index}.quantity`}
      control={control}
      rules={{ required: true }}
      render={({ field }) => (
        <input
          {...field}
          type="text"
          placeholder="数量"
          className="border p-2 w-24"
        />
      )}
    />
  </div>
))}

3. 监听字段变化并触发焦点

使用useEffect监听配料数组的变化,当数组长度增加(即添加新字段)时,聚焦最后一个输入框:

useEffect(() => {
  const ingredients = watch("ingredients");
  // 获取最后一个输入框的索引
  const lastIndex = ingredients.length - 1;
  if (lastIndex >= 0) {
    // 确保DOM已更新后再触发焦点
    requestAnimationFrame(() => {
      ingredientRefs.current[lastIndex]?.focus();
    });
  }
}, [watch("ingredients")]);

原理说明

  • 通过ref数组精准追踪每个动态输入框的DOM元素,避免React渲染后丢失引用
  • 使用requestAnimationFrame确保React完成DOM更新后再执行焦点操作,解决异步渲染导致的ref未就绪问题
  • 手动触发焦点会覆盖浏览器默认的焦点跳转行为,确保焦点落在目标输入框上

内容的提问来源于stack exchange,提问作者Oshri Moalem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:22:41