React组件中内部函数渲染的TextField无法连续输入如何解决
问题修复方案
问题根源
每次输入字符触发setAddressTest更新状态时,父组件Search会重新渲染,此时内部定义的AdvancedSearch函数会被重新创建。React会将重新创建的AdvancedSearch视为全新组件,卸载旧组件并挂载新实例,直接导致输入框焦点丢失。
修复步骤
使用React.memo缓存AdvancedSearch组件,同时将依赖的状态和回调通过props传递,避免不必要的组件卸载/重新挂载:
- 导入
memo工具:
import { useState, memo } from 'react';
- 修改
AdvancedSearch为接收props的形式,并使用memo包裹:
const AdvancedSearch = memo(({ addressTest, setAddressTest }) => { return ( <> <Grid container rowSpacing={0.4} columnSpacing={3} id="advanced_search_section"> <Grid item xs={12} sm={6} md={3}> <InputLabel htmlFor="address">Address</InputLabel> <TextField id="address" // 与InputLabel的htmlFor对应,优化可访问性 value={addressTest} onChange={(event: React.ChangeEvent<HTMLInputElement>) => { setAddressTest(event.target.value); }} /> </Grid> </Grid> </> ); });
- 在父组件中调用时传递所需props:
return ( <> <AdvancedSearch addressTest={addressTest} setAddressTest={setAddressTest} /> </> );
原理说明
React.memo会对组件的props进行浅比较,只有当props发生变化时才会重新渲染组件。由于setAddressTest是useState返回的稳定函数,只有addressTest变化时AdvancedSearch才会更新,且此时不会触发组件卸载/重新挂载,输入框的焦点得以保留。
内容的提问来源于stack exchange,提问作者Mr Ish
相关产品推荐
相关产品推荐

