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

React.js中输入框输入单个字符后失焦的原因排查

React输入框输入字符后失焦的原因及解决方法

问题原因

核心问题是自定义组件gridTemplate定义在了父组件内部。每次输入触发handleOnchange更新dataSource状态时,父组件会重新渲染,此时gridTemplate会被重新创建为一个全新的组件。原来的输入框组件会被卸载,新的输入框组件挂载,自然就失去了焦点。你之前改成onBlur没用,是因为问题根源不在事件绑定,而是组件被反复重建导致的。

解决方法

方法1:将自定义组件移到父组件外部

把gridTemplate提取到父组件的作用域之外,避免它随父组件渲染反复创建:

// 把gridTemplate移到父组件外面
const gridTemplate = (props: any) => {
  const val = props.Freight;
  return (
    <div>
      <input value={val} onChange={(event) => handleOnchange(event, props)} />
    </div>
  );
};

// 父组件
const YourParentComponent = () => {
  const [dataSource, setDataSource] = useState<any>(data);

  const handleOnchange = (event: any, props: any) => {
    const newData = [...dataSource];
    const itemIndex = newData.findIndex(
      (item) => item.OrderID === props.OrderID
    );
    newData[itemIndex].Freight = event.target.value;
    setDataSource(newData);
  };

  // ... 其他业务代码
};

方法2:用useMemo缓存自定义组件

如果gridTemplate需要依赖父组件内部的函数或状态,无法移到外部,可以用useMemo缓存组件,确保只有依赖项变化时才重新创建:

const YourParentComponent = () => {
  const [dataSource, setDataSource] = useState<any>(data);

  const handleOnchange = (event: any, props: any) => {
    const newData = [...dataSource];
    const itemIndex = newData.findIndex(
      (item) => item.OrderID === props.OrderID
    );
    newData[itemIndex].Freight = event.target.value;
    setDataSource(newData);
  };

  // 用useMemo缓存gridTemplate,依赖项为handleOnchange
  const gridTemplate = useMemo(() => {
    return (props: any) => {
      const val = props.Freight;
      return (
        <div>
          <input value={val} onChange={(event) => handleOnchange(event, props)} />
        </div>
      );
    };
  }, [handleOnchange]);

  // ... 其他业务代码
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:32:43