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

如何实现Select组件选项互斥且取消选择时恢复选项(JavaScript)

解决Select组件选项互斥(选中移除、取消恢复)的问题

需求说明

有4个初始选项列表相同的Select组件,要求:

  • 选中某一选项后,该选项从其他Select组件的选项列表中移除,避免重复选择
  • 清除Select选择或更换选项时,之前的选项能自动恢复到其他Select的列表中

现有问题

当前实现直接修改了原始选项数组listStaff,导致清除或更换选项时,已移除的选项无法恢复,永久丢失。

解决方案代码

1. 保留原始选项常量

// 原始选项列表,作为常量不修改
const listStaff = [
  {id: 1, name: 'John Doe'},
  {id: 2, name: 'Walter White'},
  {id: 3, name: 'Jesse Pinkman'},
  {id: 4, name: 'Saul Goodman'},
  {id: 5, name: 'Gus Fring'},
  {id: 6, name: 'Skyler White'}
];

2. 维护选中状态数组

// 存储4个Select的选中id,初始化为未选中状态
const [staff, setStaff] = useState([undefined, undefined, undefined, undefined]);

3. 实现选项变更处理函数

const onChangeStaff = (selectedId, index) => {
  // 创建新数组更新对应位置的选中值,清除时selectedId为undefined
  const newStaff = [...staff];
  newStaff[index] = selectedId;
  setStaff(newStaff);
};

4. 渲染Select组件(动态过滤选项)

{/* 第一个Select */}
<Select
  allowClear
  placeholder="Choose staff #1"
  onChange={(e) => onChangeStaff(e, 0)}
  value={staff[0]}
>
  {listStaff
    .filter(item => {
      // 保留当前Select的选中项,排除其他已选中的项
      return item.id === staff[0] || !staff.filter(Boolean).includes(item.id);
    })
    .map((item) => (
      <Select.Option key={item.id} value={item.id}>
        {item.name}
      </Select.Option>
    ))}
</Select>

{/* 第二个Select */}
<Select
  allowClear
  placeholder="Choose staff #2"
  onChange={(e) => onChangeStaff(e, 1)}
  value={staff[1]}
>
  {listStaff
    .filter(item => {
      return item.id === staff[1] || !staff.filter(Boolean).includes(item.id);
    })
    .map((item) => (
      <Select.Option key={item.id} value={item.id}>
        {item.name}
      </Select.Option>
    ))}
</Select>

{/* 第三个Select */}
<Select
  allowClear
  placeholder="Choose staff #3"
  onChange={(e) => onChangeStaff(e, 2)}
  value={staff[2]}
>
  {listStaff
    .filter(item => {
      return item.id === staff[2] || !staff.filter(Boolean).includes(item.id);
    })
    .map((item) => (
      <Select.Option key={item.id} value={item.id}>
        {item.name}
      </Select.Option>
    ))}
</Select>

{/* 第四个Select */}
<Select
  allowClear
  placeholder="Choose staff #4"
  onChange={(e) => onChangeStaff(e, 3)}
  value={staff[3]}
>
  {listStaff
    .filter(item => {
      return item.id === staff[3] || !staff.filter(Boolean).includes(item.id);
    })
    .map((item) => (
      <Select.Option key={item.id} value={item.id}>
        {item.name}
      </Select.Option>
    ))}
</Select>

核心逻辑说明

  • 不修改原始数组:始终基于原始listStaff动态计算每个Select的可用选项,避免数据丢失
  • 动态过滤规则:每个Select的选项包含两部分:自己当前选中的项(方便查看和修改)、排除其他所有已选中项后的剩余选项
  • 状态驱动更新:当选中或清除选项时,仅更新staff状态数组,所有Select的选项会自动重新计算,实现选项的动态移除和恢复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:50:32