react-select - 如何确保默认的 selected 项不会出现在两个下拉列表中?

react-select - How to ensure the default selected items aren't appearing in both dropdowns?

在 react-select 中,我对两个下拉选项使用相同的选项。如果一只狗在一个下拉列表中 selected,那么它不应该显示在另一个下拉列表中 - 这工作正常。

现在我已经添加了默认的 selected 项目,它没有像预期的那样工作。在第一个下拉列表中,'Bulldog' 不应该对 select 可用。在第二个下拉列表中,'Chihuahua' 不应该对 select 可用,因为它们都已经 selected(参见演示)。

它相当复杂 UI 并且有点超出我的舒适范围。关于如何让它工作的任何想法?

下拉数据和组件:

export const dogOptions = [
  { value: 1, label: "Chihuahua", firstDropdown: true, secondDropdown: false },
  { value: 2, label: "Bulldog", firstDropdown: false, secondDropdown: true },
  { value: 3, label: "Dachshund", firstDropdown: true, secondDropdown: false },
  { value: 4, label: "Akita", firstDropdown: false, secondDropdown: false },
  { value: 5, label: "Lab", firstDropdown: false, secondDropdown: false }
];

export default () => {
  const [options1, setOption1] = React.useState(options);
  const [options2, setOption2] = React.useState(options);

  return (
    <>
      <p>First dropdown</p>
      <Select
        isMulti
        options={options1}
        defaultValue={options.filter((o) => o.firstDropdown === true)}
        onChange={(v1) => {
          setOption2(options.filter((o) => o.firstDropdown === true));
        }}
      />
      <div style={{ height: 30 }} />
      <p>Second dropdown</p>
      <Select
        isMulti
        options={options2}
        defaultValue={options.filter((o) => o.secondDropdown === true)}
        onChange={(v2, a) => {
          setOption1(options.filter((o1) => !v2.includes(o1)));
        }}
      />
    </>
  );
};

您可以在 useState 中添加初始化回调来为 Select:

设置初始选项
const [options1, setOption1] = React.useState(() =>
  options.filter((o) => o !== defaultValue2)
);
const [options2, setOption2] = React.useState(() =>
  options.filter((o) => o !== defaultValue1)
);

如果两个默认值相同,则它不是有效状态,您可以使用 useEffect:

检测并抛出异常
useEffect(() => {
  if (defaultValue1 === defaultValue2 && defaultValue1 !== undefined) {
    throw new Error("defaultValue1 and defaultValue2 must not be the same");
  }
}, [defaultValue1, defaultValue2]);