程序化打开Material-UI Select导致TextField失焦的问题咨询
实现方案
核心原因
Material UI的Select组件底层依赖Menu组件,默认打开时会自动将焦点移动到自身或首个菜单项,这是触发TextField失焦的根本原因。
具体修改步骤
- 为TextField绑定React ref,用于后续主动控制输入框焦点
- 给Select添加
disableAutoFocus、disableEnforceFocus属性,禁止组件打开时自动抢占焦点 - 改造Select的
onOpen回调,在下拉框完成展开后主动将焦点切回输入框
完整修改后代码
import * as React from 'react'; import { FormControl, InputLabel, MenuItem, TextField, Select } from '@material-ui/core'; export default function AddressSearchLookup(props: any) { const [key, setKey] = React.useState(''); const [openSelect, setOpenSelect] = React.useState(false); // 新增TextField引用 const keyTextFieldRef = React.useRef<HTMLInputElement>(null); const [filteredAddresses, setFilteredAddresses] = React.useState([] as any); React.useEffect(() => { if (key.length > 0) { var addrs = props.Addresses; addrs = addrs.filter((a: any) => a.key.toLowerCase().startsWith(key.toLowerCase())); setFilteredAddresses(addrs); } else { props.OnAddressChange(''); } }, [key]); const onSelectAddress = (e:any) => { if(key !== e.target.value) { setKey(e.target.value); } props.OnAddressChange(e.target.value); // 可选:选中地址后重新把焦点切回输入框,支持用户继续输入修改 setTimeout(() => { keyTextFieldRef.current?.focus(); }, 0); } const onKeyFieldChanged = (e: any) => { if (key !== e.target.value) { setKey(e.target.value); } setOpenSelect(true); } return (<span style={{ width: '100%', display: 'flex', alignItems: 'center' }}> <FormControl variant="outlined" style={{ width: '30%' }}> <TextField ref={keyTextFieldRef} value={key} variant="outlined" label={"Key"} name="key-label-placeholder" onChange={onKeyFieldChanged} inputProps={{ name: 'keySearchAddress', id: 'keySearchAddress' }} /> </FormControl> <FormControl variant="outlined" style={{ width: '70%' }}> <InputLabel id="address-select-outlined-label" >Adresse</InputLabel> <Select labelId="address-select-outlined-label" id="address-select-select-outlined" name="address" open={openSelect} onClose={() => setOpenSelect(false)} onOpen={() => { setOpenSelect(true); // 等待Select渲染完成后切回输入框焦点 setTimeout(() => { keyTextFieldRef.current?.focus(); }, 0); }} // 新增禁止自动聚焦属性 disableAutoFocus={true} disableEnforceFocus={true} value={props.Address} onChange={onSelectAddress} label="Addresse" displayEmpty > { filteredAddresses.map((ctr: any) => { if ('text' in ctr) return (<MenuItem key={ctr.key} value={ctr.key}>{ctr.text}</MenuItem>); else return null; }) } </Select> </FormControl> </span>) }
可选优化
如果需要支持用户通过上下方向键在下拉菜单中切换选项,同时保持输入框焦点,可以给TextField添加onKeyDown事件监听,手动控制选中的菜单项索引即可。
内容的提问来源于stack exchange,提问作者Jimbot
相关产品推荐
相关产品推荐

