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
相关产品推荐
相关产品推荐

