React表单中实现两个多选下拉框选项互斥禁用的方案
实现React多选下拉框的选项互斥禁用
核心实现思路
要达成「包含项选中后,不包含项对应选项禁用」的需求,只需完成以下关键操作:
- 给「不包含项」的每个选项添加禁用判断,检查该选项是否已被选入「包含项」
- (可选)双向同步选中状态,避免同一选项同时出现在两个下拉框中
修改后的完整代码
import React from 'react'; import { FormControl, InputLabel, Select, OutlinedInput, MenuItem, Checkbox, ListItemText } from '@mui/material'; // 若两个下拉框选项一致,可共用此数组(按需替换为你的实际选项) const optionArr = ["选项1", "选项2", "选项3", "选项4"]; export default function MutuallyExclusiveSelects() { const [personwhatIncludeItems, setPersonwhatIncludeItems] = React.useState([]); const [personnotIncludeItems, setPersonnotIncludeItems] = React.useState([]); const handlenotIncludeItemsChange = (event) => { const { target: { value } } = event; const newNotIncludeItems = typeof value === "string" ? value.split(",") : value; // 移除包含项中与新增不包含项重复的选项 setPersonwhatIncludeItems(prev => prev.filter(item => !newNotIncludeItems.includes(item)) ); setPersonnotIncludeItems(newNotIncludeItems); }; const handlewhatIncludeItemsChange = (event) => { const { target: { value } } = event; const newIncludeItems = typeof value === "string" ? value.split(",") : value; // 移除不包含项中与新增包含项重复的选项 setPersonnotIncludeItems(prev => prev.filter(item => !newIncludeItems.includes(item)) ); setPersonwhatIncludeItems(newIncludeItems); }; // 补充MenuProps基础配置(原代码未给出,按需调整样式) const MenuProps = { PaperProps: { style: { maxHeight: 480, width: 250, }, }, }; return ( <div className="row"> <div className="col-6 mt-2 mb-2"> <FormControl fullWidth> <InputLabel id="multiple-include-label"> Includes</InputLabel> <Select labelId="whatInclude-multiple-checkbox-label" id="whatInclude-multiple-checkbox" multiple value={personwhatIncludeItems} onChange={handlewhatIncludeItemsChange} input={<OutlinedInput label="Tag" />} renderValue={(selected) => selected.join(", ")} MenuProps={MenuProps} > {optionArr.map((whatIncludeItems) => ( <MenuItem key={whatIncludeItems} value={whatIncludeItems} // 可选:禁用已在不包含项中选中的选项,实现双向互斥 disabled={personnotIncludeItems.includes(whatIncludeItems)} > <Checkbox checked={personwhatIncludeItems.indexOf(whatIncludeItems) > -1} /> <ListItemText primary={whatIncludeItems} /> </MenuItem> ))} </Select> </FormControl> </div> <div className="col-6 mt-2 mb-2"> <FormControl fullWidth> <InputLabel id="multiple-not-include-label"> Not Includes</InputLabel> <Select labelId="whatnotInclude-multiple-checkbox-label" id="whatnotInclude-multiple-checkbox" multiple value={personnotIncludeItems} onChange={handlenotIncludeItemsChange} input={<OutlinedInput label="Not Include" />} renderValue={(selected) => selected.join(", ")} MenuProps={MenuProps} > {optionArr.map((notIncludeItems) => ( <MenuItem key={notIncludeItems} value={notIncludeItems} // 核心逻辑:禁用已在包含项中选中的选项 disabled={personwhatIncludeItems.includes(notIncludeItems)} > <Checkbox checked={personnotIncludeItems.indexOf(notIncludeItems) > -1} /> <ListItemText primary={notIncludeItems} /> </MenuItem> ))} </Select> </FormControl> </div> </div> ); }
关键修改点说明
- 禁用逻辑:在「不包含项」的
MenuItem上添加disabled={personwhatIncludeItems.includes(notIncludeItems)},实时检查当前选项是否已被选入包含项,若已选中则禁用该选项。 - 双向状态同步:在两个下拉框的
onChange事件中,过滤掉对方已选中的选项,确保同一选项不会同时出现在包含和不包含列表中。 - 选项数组复用:如果两个下拉框的选项集合一致,建议共用同一个数组,避免维护两个重复数组增加冗余。
内容的提问来源于stack exchange,提问作者Afaq Shahid Khan
相关产品推荐
相关产品推荐

