MUI Select下拉菜单隐形但未消失且未失焦的异常问题求助
修复MUI Select组件下拉菜单隐形但未消失导致页面冻结的问题
问题现象
MUI Select组件在前3-4次使用正常,但约第4次时,下拉菜单变为隐形却未消失——鼠标悬停原菜单区域仍显示指针,点击可选中对应选项且视图更新,但页面内其他交互控件(按钮、复选框等)无法点击,视图近乎冻结,隐形下拉菜单持续存在。
现有实现代码
Select组件代码
<FormControl required fullWidth size="small"> <InputLabel id={`${elementName}-label`}>{elementLabel}</InputLabel> <Select labelId={`${elementName}-label`} id={`${elementName}`} name={`${elementName}`} value={elementValue} label={elementLabel} onChange={(e) => changeHandler(e, setForm)} > {elementArrayOptions.map(option => <MenuItem value={option} key={option}>{option}</MenuItem>)} </Select> </FormControl>
状态更新函数代码
const handleResultsSelect = (e, setForm) => { setForm(e.target.value) }
修复方案
1. 确保MenuItem的key属性唯一
当前用option作为MenuItem的key,若选项存在重复值,会触发React错误的DOM复用逻辑,导致组件状态异常。修改为结合索引的唯一key:
{elementArrayOptions.map((option, index) => ( <MenuItem value={option} key={`${option}-${index}`}> {option} </MenuItem> ))}
2. 优化状态更新逻辑
如果setForm是用于更新复杂表单状态的函数,使用函数式更新确保获取最新状态,避免状态不同步:
const handleResultsSelect = (e, setForm) => { setForm(prevState => ({ ...prevState, [e.target.name]: e.target.value })); };
3. 手动控制下拉菜单的打开/关闭状态
通过显式维护菜单的open状态,在选中选项后强制关闭菜单,避免菜单DOM残留:
// 在组件内部添加状态声明 const [open, setOpen] = useState(false); // 修改Select组件属性 <Select labelId={`${elementName}-label`} id={`${elementName}`} name={`${elementName}`} value={elementValue} label={elementLabel} onChange={(e) => { changeHandler(e, setForm); setOpen(false); // 选中后强制关闭 }} open={open} onOpen={() => setOpen(true)} onClose={() => setOpen(false)} MenuProps={{ onClose: () => setOpen(false) }} >
4. 减少不必要的重渲染
如果Select组件被频繁重渲染的父组件包裹,用React.memo包裹组件,避免无意义的DOM更新:
const CustomSelect = React.memo(({ elementName, elementLabel, elementValue, elementArrayOptions, changeHandler, setForm }) => { return ( <FormControl required fullWidth size="small"> <InputLabel id={`${elementName}-label`}>{elementLabel}</InputLabel> <Select labelId={`${elementName}-label`} id={`${elementName}`} name={`${elementName}`} value={elementValue} label={elementLabel} onChange={(e) => changeHandler(e, setForm)} > {elementArrayOptions.map((option, index) => ( <MenuItem value={option} key={`${option}-${index}`}> {option} </MenuItem> ))} </Select> </FormControl> ); });
内容的提问来源于stack exchange,提问作者Philip Sopher
相关产品推荐
相关产品推荐

