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

程序化打开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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:06:03