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

React中点击按钮后输入框首次无法获取焦点问题求助

问题:点击按钮后Input首次无法获得焦点,后续操作正常

点击"Enable Input"按钮后,对应的input元素首次无法获得焦点,但再次点击按钮时可以正常聚焦。

原因分析

React的状态更新是异步批量处理的。在按钮点击的回调函数中,调用setInput1("")和setConfig(...)后,组件不会立刻重新渲染,此时input仍然处于disabled={true}的状态,直接调用ref1.current.focus()会因为元素处于禁用状态而失效。当后续点击按钮时,状态已经完成更新,input不再禁用,所以focus操作能正常生效。

解决方案

方法1:使用useEffect监听状态变化

通过useEffect监听config中对应项的变化,当状态更新为允许输入(即config1/config2变为false)时,执行focus操作:

import React, { useEffect, useRef, useState } from "react";
import { render } from "react-dom";
import * as data from "./messages.json";

const App = () => {
  return <Test {...{ alreadySetVal1: true, alreadySetVal2: true }} />;
};

const Test = ({ alreadySetVal1, alreadySetVal2 }) => {
  const [input1, setInput1] = useState(alreadySetVal1 ? "Already Set" : "");
  const [input2, setInput2] = useState(alreadySetVal2 ? "Already Set" : "");
  const [config, setConfig] = useState({
    config1: !!input1,
    config2: !!input2
  });
  const ref1 = useRef(null);
  const ref2 = useRef(null);

  // 监听config1变化,完成渲染后聚焦input1
  useEffect(() => {
    if (!config.config1 && ref1.current) {
      ref1.current.focus();
    }
  }, [config.config1]);

  // 监听config2变化,完成渲染后聚焦input2
  useEffect(() => {
    if (!config.config2 && ref2.current) {
      ref2.current.focus();
    }
  }, [config.config2]);

  return (
    <>
      <div>
        <input
          disabled={config.config1}
          value={input1}
          ref={ref1}
          type={config.config1 ? "text" : "password"}
          onChange={(e) => setInput1(e.target.value)}
        />
        <span
          onClick={() => {
            setInput1("");
            setConfig({ ...config, config1: false });
          }}
        >
          Enable Input 1
        </span>
      </div>
      <div>
        <input
          disabled={config.config2}
          value={input2}
          ref={ref2}
          type={config.config2 ? "text" : "password"}
          onChange={(e) => setInput2(e.target.value)}
        />
        <span
          onClick={() => {
            setInput2("");
            setConfig({ ...config, config2: false });
          }}
        >
          Enable Input 2
        </span>
      </div>
    </>
  );
};

render(<App messages={data.messages} />, document.getElementById("root"));

方法2:使用setTimeout延迟执行focus

利用setTimeout让React完成状态更新和渲染后再执行focus操作:

// 修改按钮点击回调部分示例
onClick={() => {
  setInput1("");
  setConfig({ ...config, config1: false });
  setTimeout(() => {
    ref1.current?.focus();
  }, 0);
}}

两种方法都能解决首次点击无法聚焦的问题,推荐使用方法1,因为它更符合React的状态更新机制,避免依赖定时器的不确定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:46:03