React输入框首次按/键无法聚焦问题排查与解决
问题分析与修复:按下/键时Input首次无法聚焦的问题
需求与问题
需求:按下/键时,切换input元素从display: none到display: block状态并自动获得焦点。
当前代码问题:首次按下/键,input仅显示但未聚焦,需再次按下才会触发聚焦。
问题原因
首次按下/键时,setIsInputFocused(true)会触发组件重新渲染,但React的状态更新是异步的——调用setIsInputFocused后,isInputFocused并不会立刻变为true,此时input元素还处于display: none的状态(DOM尚未完成更新),调用inputRef.current?.focus()自然不会生效。
第二次按下/键时,isInputFocused已经是true,input已经处于显示状态,所以focus()能正常工作。
修复方案
核心思路:监听状态变化,确保DOM更新后再聚焦
移除handleDocumentKeyDown里的focus()调用,新增一个依赖isInputFocused的useEffect,当状态变为true时再执行聚焦操作:
修改后的完整代码:
import React from "react"; import { useState, useEffect, useRef, ChangeEvent } from "react"; import { createRoot } from "react-dom/client"; function App() { const [inputValue] = useState(""); const [isInputFocused, setIsInputFocused] = useState(false); const inputRef = useRef<HTMLInputElement | null>(null); function handleInputChange(event: ChangeEvent<HTMLInputElement>) { // some code } function handleInputBlur(event: ChangeEvent<HTMLInputElement>) { setIsInputFocused(false); } function handleDocumentKeyDown(event: any) { if (event.key === "/") { event.preventDefault(); setIsInputFocused(true); // 移除此处的focus调用 } } useEffect(() => { document.addEventListener("keydown", handleDocumentKeyDown); return () => { document.removeEventListener("keydown", handleDocumentKeyDown); }; }, []); // 新增useEffect,监听isInputFocused状态变化 useEffect(() => { if (isInputFocused && inputRef.current) { inputRef.current.focus(); } }, [isInputFocused]); return ( <div id="keys" className={isInputFocused ? "active" : "inactive"}> <input ref={inputRef} type="text" onChange={handleInputChange} onBlur={handleInputBlur} value={inputValue} /> </div> ); } const root = createRoot(document.getElementById("root")!); root.render(<App />);
方案说明
React状态更新后会触发组件重新渲染,当isInputFocused变为true时,DOM已经完成更新(input元素从隐藏变为显示),此时调用focus()能确保input处于可聚焦状态,首次按下/键就能直接生效。
另外,原代码中初始useEffect里的inputRef.current?.focus()可以移除,因为初始状态下input是隐藏的,这个调用没有实际意义。
内容的提问来源于stack exchange,提问作者wyc
相关产品推荐
相关产品推荐

