如何自定义 Select 以显示以逗号分隔的 selected 选项?反应-select

How to customize Select to display selected options separated by comma? react-select

我尝试从 react-select 库自定义 Select 组件。 我用 span 元素自定义了 multiSelectValue 并在标签中添加了逗号。但它不适用于输入。当下拉列表中的项目 selected 时,它按预期工作。但是,当我尝试为搜索选项输入值时,输入会被聚焦,并且 span 项目向左移动,结果字段变为空。

多个select

export default function App() {
  const [values, setValues] = useState([]);

  return (
    <div className="root">
      <Select
        styles={styles}
        isSearchable
        isMulti
        getOptionValue={(option) => option["value"]}
        options={options}
        value={values}
        onChange={(options) => {
          setValues(() => options);
        }}
        components={{
          MultiValue: CustomMultiValue
        }}
      />
    </div>
  );
}

自定义 selected 值

function CustomMultiValue(props) {
  const { getValue, data } = props;

  const selectedOptions = getValue();
  const currentOptionIdx = selectedOptions.findIndex(
    (option) => option.value === data.value
  );

  return (
    <span>
      {data.label}
      {currentOptionIdx === selectedOptions.length - 1 ? "" : ", "}
    </span>
  );
}

沙盒项目https://codesandbox.io/s/boring-knuth-kfo1e?file=/src/CustomMultiValue.js

我认为您的代码没有任何问题。也许你应该尝试增加 Select 的宽度,这样你就可以看到所有其他 multi-values 被剪裁在你的 codesandbox 中。

const width = "500px";
const styles = {
  control: (provided) => ({
    ...provided,
    width
  }),
  menu: (provided) => ({
    ...provided,
    width
  }),
  ...
};

我找到了解决办法。 要实现它需要做 2 个操作:

  • 在 select 打开时更改 ValueContainer 的溢出样式
  • 菜单关闭时向左滚动

当菜单打开时使用 overflow:unset - 因此输入将在 selected 值的末尾正确显示 当菜单关闭时,使用 overflow:ellipsis 显示第一个 selected 值并需要对它们进行切片

  valueContainer: (provided, state) => {
    const disableOverflow =
      state.selectProps.isSearchable && state.selectProps.menuIsOpen;

    return {
      whiteSpace: "nowrap",
      textOverflow: disableOverflow ? "unset" : "ellipsis",
      overflow: "hidden",
      flex: "1 1 0%",
      position: "relative"
    };
  },

要向左滚动需要使用自定义 ValueContainer 并将 ref 传递给该容器。检查 menuIsOpen 何时更改为 false 并在那一刻向左滚动。

function CustomMultiValueContainer(props) {
  const {
    selectProps: { menuIsOpen }
  } = props;
  const containerRef = useRef(null);
  const styles = props.getStyles("valueContainer", props);

  useEffect(() => {
    if (!menuIsOpen) {
      if (containerRef && containerRef.current) {
        containerRef.current.scrollLeft = 0;
      }
    }
  }, [menuIsOpen]);

  return (
    <div ref={containerRef} style={styles}>
      {props.children}
    </div>
  );
}