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

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;

问题原因

  1. autoFocus={true}的错误使用:
    这个属性会在组件每次渲染时强制输入框获得焦点。当你点击输入框外部失焦后,组件因userInput变化重新渲染,autoFocus会再次触发输入框聚焦,浏览器的异常交互逻辑可能导致输入框内容回退到之前的状态。

  2. 防抖逻辑完全无效:
    在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:22:46