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

TS-React项目中react-hook-form提交后如何让输入框失焦

实现方案

你无法定位输入框的核心原因是:在Controller的render方法中解构field属性时,单独拆分出了ref字段但没有绑定到InputText组件上,导致表单实例没有持有输入框的DOM引用,自然无法在提交回调中触达目标元素。
以下提供两种可直接落地的实现方式:

方案1:自定义Ref绑定(兼容性最好,推荐)

使用React原生useRef创建输入框引用,同时兼容react-hook-form的内部ref绑定逻辑,不破坏原有表单校验、值同步能力,提交时直接调用ref上的blur方法即可:

import { FC, useRef } from "react";
import { Controller, useForm } from "react-hook-form";

// 提前定义好表单类型避免any
type Basket = {
  scanId: string;
}

const BasketContainer: FC = () => {
  // 新增扫描输入框的DOM引用
  const scanIdInputRef = useRef<HTMLInputElement>(null);

  const { 
    control, 
    handleSubmit, 
    setValue, 
    watch, 
    getValues, 
    reset, 
    formState: {errors}
  } = useForm<Basket>({
    defaultValues: {
      scanId: ""
    }
  });

  const handleScanIdSubmit = (data: Basket) => {
    // 这里写原有fetch请求、业务处理逻辑
    // 所有逻辑执行完成后触发输入框失焦
    scanIdInputRef.current?.blur();
  };

  return (
    <form onSubmit={handleSubmit(handleScanIdSubmit)}>
      <Controller
        control={control}
        name="scanId"
        rules={{required: "Field required"}}
        render={({field: {ref, ...restField}}) => (
          <InputText  
            {...restField}
            // 同时绑定rhf内部ref和自定义ref,不影响原有表单逻辑
            ref={(element) => {
              ref(element);
              scanIdInputRef.current = element;
            }}
            type="text"
            label="ID"
            errorMessage={errors.scanId?.message}
          />
        )}
      />
      <Button type="submit" />
    </form>
  );
};

注意:如果你的InputText是自定义组件,需要确认组件做了forwardRef透传,才能拿到真实的input DOM节点。如果组件未做ref透传,可以给输入框加固定id,提交时通过document.getElementById("scan-id-input")?.blur()实现效果,只是这种方式优先度低于ref方案。


方案2:直接透传Controller提供的ref

如果不需要自定义持有ref,直接把Controller field里的所有属性全量传给InputText即可,提交时可以通过react-hook-form的字段引用触发blur:

// Controller部分修改为全量透传field
<Controller
  control={control}
  name="scanId"
  rules={{required: "Field required"}}
  render={({field}) => (
    <InputText  
      {...field}
      type="text"
      label="ID"
      errorMessage={errors.scanId?.message}
    />
  )}
/>

提交回调里通过表单内部字段引用触发失焦:

const handleScanIdSubmit = (data: Basket) => {
  // 原有业务逻辑
  // 触发字段失焦
  control._fields.scanId?._f.ref?.blur();
};

这个写法依赖react-hook-form的内部属性结构,版本升级时可能有变动,优先选择方案1。


内容的提问来源于stack exchange,提问作者KaraStras J.B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:09:16