React TS组件中useState致输入框失焦及全局重渲染问题求助
解决方案
1. 仅渲染部分内容的替代方案
有两种核心思路:
- 拆分独立子组件:将筛选输入框、表格、分页控件拆分为独立的函数组件,让各组件仅在自身状态或依赖props变化时重渲染。
- 缓存计算结果与回调函数:使用
useMemo缓存表格内容的计算结果,使用useCallback缓存事件处理函数,避免无意义的重渲染触发。
2. 保留值持久化+阻止不必要重渲染的具体实现
结合你的代码,按以下步骤修改:
步骤1:修正基础错误
首先修复代码中的拼写错误:将onchange改为React标准的onChange事件名,这是确保事件正常触发的前提。
步骤2:用useCallback缓存事件处理函数
每次组件重渲染时,普通函数会被重新创建,导致依赖该函数的子组件误以为props变化而重渲染。用useCallback缓存onchangeval,确保函数引用稳定:
import { useState, useCallback, useMemo } from 'react'; export const datagrid = (props: datagridprops) => { const [searchValue, setSearchValue] = useState<string|undefined>(); // 用useCallback缓存回调,依赖为空(setSearchValue由useState返回,引用稳定) const onchangeval = useCallback((event: React.ChangeEvent<HTMLInputElement>) => { setSearchValue(event.target.value); }, []); // ... }
步骤3:用useMemo缓存表格内容
如果renderData函数的计算逻辑较重,每次重渲染都会重新执行并生成新的表格内容,导致表格重渲染。用useMemo缓存计算结果,仅当依赖项变化时才重新计算:
// 假设renderData依赖props.data和searchValue const tableContent = useMemo(() => { return renderData(props.data, searchValue); // 传入必要依赖 }, [props.data, searchValue]); // 明确依赖项,只有这些值变化时才重新计算
步骤4:用React.memo包裹子组件(可选但推荐)
如果将表格、分页或筛选输入框拆分为独立子组件,使用React.memo包裹它们,让组件仅在props浅比较变化时重渲染:
示例:拆分筛选输入框组件
import { memo } from 'react'; // 用memo包裹,仅当value或onChange变化时重渲染 const FilterInput = memo(({ value, onChange }: { value?: string; onChange: (e: React.ChangeEvent<HTMLInputElement>) => void }) => { return <input value={value} onChange={onChange} />; }); // 在父组件中使用 export const datagrid = (props: datagridprops) => { // ... 之前的代码 return(<> <FilterInput value={searchValue} onChange={onchangeval} /> <table>{tableContent}</table> {/* 如果分页是自定义组件,同样用memo包裹 */} <PaginationControl /> </>); }
步骤5:优化分页组件重渲染
如果分页控件是第三方组件或自定义组件,确保传递给它的props(如当前页码、总页数)仅在必要时变化。如果props稳定,结合React.memo可以完全阻止其无意义重渲染。
这些改动能解决焦点丢失问题的原因:
当父组件因searchValue更新而重渲染时,缓存后的表格内容、回调函数不会产生新的引用,配合React.memo的子组件只会在真正需要时更新,避免了DOM结构的频繁重建,从而保留输入框的焦点。
内容的提问来源于stack exchange,提问作者IHaveAQuestion
相关产品推荐
相关产品推荐

