在react-select中使用自定义ValueContainer维护默认的打开/关闭行为

问题描述 投票:0回答:1

我需要稍微自定义一个反应选择下拉列表。 它是多项选择,我的目标是当用户选择多个选项时,所选选项仅占用框中可用的水平空间。 溢出应该用椭圆处理。

默认行为 - 溢出项目换行到下一行并使框高度增长:

enter image description here

所需的行为 - 自定义渲染,带椭圆

enter image description here

我实现此目的的策略是在选择中使用自定义组件

ValueContainer
:

const ValueContainer = (props) => (
  <div
    {...props.innerProps}
    style={{
      whiteSpace: "nowrap",
      overflow: "hidden",
      textOverflow: "ellipsis",
    }}
  >
    {props.selectProps?.value?.map((p) => p.label).join(", ")}
  </div>
);



const MyComponent = () => {
  // state logic here

  return (
     <Select
        options={options}
        value={value}
        isMulti
        onChange={(value) => setValue(value)}
        components={{ ValueContainer }}
      />
  );

这确实有效,正如您在此代码和框中看到的那样。

但是,我似乎失去了默认行为。 在沙箱的左侧示例中(默认如上所示),当您单击下拉列表的任何部分(现有选择、空白区域、下拉指示器等)时,下拉列表将打开。 这就是我想要的行为。 在我的自定义示例中,单击列表不会打开下拉菜单 - 您必须专门单击微小的下拉箭头才能将其打开。 同样,当其打开时,默认行为有一个单击离开处理程序,单击屏幕上的任意位置都会关闭菜单。 此自定义

ValueContainer
组件也会丢失该行为。

如何在使用自定义

ValueContainer
组件时保持此自定义打开/关闭单击行为? 正如文档中所述,
innerRef
的道具上似乎没有
ValueContainer
。 这些道具中是否有我缺少的
setOpen
道具? 有没有更好的方法可以达到我想要的效果?

javascript reactjs react-select
1个回答
0
投票

由于您为 ValueContainer 使用自定义组件并且不再返回其默认子组件,因此您不再渲染输入,因此无法访问其模糊事件(有关更多详细信息,请参阅此答案

但是,在您的情况下,您不必使用自定义 ValueContainer 组件。 一种可能的解决方法是使用自定义多值组件来连接所有选定的值。

const MultiValue = (props) => {
  const selectedValues = props.getValue();

  // Render only the first value
  if (props.index > 0) return null;

  // Instead of the first value, display a string with all the concatenated values
  const displayedValue = selectedValues.map((value) => value.label).join(",");

  return (
    <div
      style={{
        whiteSpace: "nowrap",
        overflow: "hidden",
        textOverflow: "ellipsis",
      }}
      {...props.innerProps}
    >
      {displayedValue}
    </div>
  );
};

您还需要对值容器进行细微的样式调整

<Select
   options={this.options}
   value={this.state.value2}
   isMulti
   onChange={(value) => this.setState({ value2: value })}
   defaultValue={{ label: 2002, value: 2002 }}
   components={{ MultiValue }}
   styles={{
      valueContainer: (base) => ({ ...base, flexWrap: "nowrap" }),
   }}
/>

从您的初始 Codesandbox 中对分叉进行的更改

一个可以说更好的解决方案是修改自定义 MultiValue 组件来为每个值呈现一个字符串,但您必须以其他方式实现省略号溢出。

© www.soinside.com 2019 - 2024. All rights reserved.