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
相关产品推荐
相关产品推荐

