React输入框失焦后回退至原状态的问题排查求助
输入框失焦后回退到之前状态的问题排查
输入框失去焦点后会重新渲染回之前的状态,以下是测试代码:
import logo from "./logo.svg"; import "./App.css"; import { useEffect, useState } from "react"; const items = ["터미널", "미나리", "터보"]; function App() { const [keyword, setKeyword] = useState(""); const [userInput, setUserInput] = useState(""); const changeInput = (e) => { const value = e.target.value; setUserInput(value); setKeyword(value); }; const debounceFunction = (callback, delay) => { let timer; return (args) => { clearTimeout(timer); timer = setTimeout(() => callback(args), delay); }; }; const filtering = () => { items.filter((item) => item === keyword); }; useEffect(() => { console.log("call"); console.log("userInput", userInput); console.log("keyword", keyword); debounceFunction(filtering, 500); }, [userInput]); return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <input value={userInput} onChange={changeInput} autoFocus={true}/> <p> Edit <code>src/App.js</code> and save to reload. </p> <ul> {items.map((item) => ( <li key={item}>{item}</li> ))} </ul> </header> </div> ); } export default App;
问题原因
autoFocus={true}的错误使用:
这个属性会在组件每次渲染时强制输入框获得焦点。当你点击输入框外部失焦后,组件因userInput变化重新渲染,autoFocus会再次触发输入框聚焦,浏览器的异常交互逻辑可能导致输入框内容回退到之前的状态。防抖逻辑完全无效:
在useEffect中仅创建了防抖函数,但没有执行返回的防抖方法,filtering函数从未被调用;同时防抖函数未做缓存,每次组件渲染都会新建实例,完全起不到防抖作用。
修复方案
替换
autoFocus实现初始聚焦:
移除输入框的autoFocus={true},改用useEffect仅在组件首次挂载时触发聚焦:useEffect(() => { const input = document.querySelector('input'); input?.focus(); }, []);修复防抖逻辑:
用useCallback缓存防抖函数,确保每次渲染复用同一实例,并在useEffect中正确调用:import { useEffect, useState, useCallback } from "react"; // ...其他代码不变 const debounceFunction = (callback, delay) => { let timer; return (args) => { clearTimeout(timer); timer = setTimeout(() => callback(args), delay); }; }; const filtering = () => { const result = items.filter((item) => item.includes(keyword)); console.log(result); // 这里可以处理过滤结果 }; // 缓存防抖后的过滤函数 const debouncedFilter = useCallback(debounceFunction(filtering, 500), [keyword]); useEffect(() => { debouncedFilter(); }, [userInput, debouncedFilter]);简化状态(可选):
keyword和userInput同步更新,可合并为一个状态变量,减少冗余:const [keyword, setKeyword] = useState(""); const changeInput = (e) => { setKeyword(e.target.value); };
内容的提问来源于stack exchange,提问作者yooo
相关产品推荐
相关产品推荐

