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

MUI Select组件问题:一个菜单打开时,另一个需两次点击才能打开

解决Material UI Select组件切换需两次点击的问题

我开发的应用里有两个并排的Dropdown(Select组件),暂称A和B。当A的菜单展开时,点击B想打开它的菜单,Material UI默认得点两次:先关掉A,再打开B。Menu组件也存在类似问题。推测是点击事件未冒泡导致的,能不能覆盖这个默认行为?

解决方案

通过全局监听点击事件,在点击另一个Select组件时主动关闭当前展开的菜单,并触发目标组件的展开,实现一次点击切换的效果。

修改后的Dropdown组件代码

import { useState, useEffect, useRef } from 'react';
import { InputLabel, MenuItem, FormControl, Select } from '@mui/material';

const Dropdown = ({ value, label, options, setter, id }) => {
    const [open, setOpen] = useState(false);
    const selectRef = useRef(null);

    const handleChange = (event) => {
        setter(event.target.value);
    };

    useEffect(() => {
        const handleGlobalClick = (e) => {
            if (selectRef.current && !selectRef.current.contains(e.target)) {
                const targetSelect = e.target.closest('.MuiSelect-root');
                if (targetSelect && targetSelect.id !== id) {
                    setOpen(false);
                    targetSelect.click();
                }
            }
        };

        document.addEventListener('click', handleGlobalClick);
        return () => document.removeEventListener('click', handleGlobalClick);
    }, [id]);

    return (
        <FormControl
            variant='outlined'
            size="small"
            sx={{
                minWidth: "120px",
                backgroundColor: "#eb6060",
                borderRadius: "5px",
                border: "1px solid black",
                '& .MuiOutlinedInput-notchedOutline': {
                    border: 'none',
                },
            }}
        >
            <InputLabel
                shrink={false}
                sx={{
                    color: "black",
                    opacity: 0.6,
                    "&.Mui-focused": {
                        color: "black",
                        opacity: 0.6,
                    },
                }}
            >
                {value === "" ? label : ""}
            </InputLabel>
            <Select
                ref={selectRef}
                id={id}
                onChange={handleChange}
                label={value === "" ? label : ""}
                value={value}
                open={open}
                onOpen={() => setOpen(true)}
                onClose={() => {
                    setOpen(false);
                    setTimeout(() => {
                        document.activeElement.blur();
                    }, 0);
                }}
                sx={{
                    "&:hover": {
                        backgroundColor: "#b34b4b",
                    },
                    "&.Mui-focused": {
                        backgroundColor: "#b34b4b",
                    },
                }}
            >
                {options.map((option) => (
                    <MenuItem
                        key={option.code}
                        value={option.code}
                        sx={{
                            "&.Mui-focusVisible": {
                                backgroundColor: "white",
                            },
                            "&.MuiMenuItem-root:hover": {
                                backgroundColor: "#D3D3D3",
                            }
                        }}
                    >
                        {option.alias}
                    </MenuItem>
                ))}
            </Select>
        </FormControl>
    );
};

export default Dropdown;

父组件使用示例

import { useState } from 'react';
import Dropdown from './Dropdown';

const ParentComponent = () => {
    const [valueA, setValueA] = useState("");
    const [valueB, setValueB] = useState("");
    // 示例选项数据
    const options = [
        { code: "opt1", alias: "选项1" },
        { code: "opt2", alias: "选项2" },
        { code: "opt3", alias: "选项3" }
    ];

    return (
        <div style={{ display: 'flex', gap: '16px', padding: '20px' }}>
            <Dropdown 
                id="select-a" 
                value={valueA} 
                label="选择A" 
                options={options} 
                setter={setValueA} 
            />
            <Dropdown 
                id="select-b" 
                value={valueB} 
                label="选择B" 
                options={options} 
                setter={setValueB} 
            />
        </div>
    );
};

export default ParentComponent;

内容的提问来源于stack exchange,提问作者WesternCreamCheese

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:37:04