自定义组件“ValueContainer”的 React-Select 失去焦点

IT技术 reactjs react-select
2021-04-25 18:14:54

我们有一个用例,我们必须根据选择的选项数量为多选下拉列表呈现多个不同版本的值容器。下面的代码片段显示了其中一种情况。这个的另一个版本呈现一个<SingleValue />而不是占位符。

<ValueContainer {...props}>
    <Placeholder {...props}>
    {!props.selectProps.inputValue && `${length} selected`}
    </Placeholder>
    {children[1]}
</ValueContainer>

这似乎运行良好,但是我们在选择其中一个选项时会丢失键盘导航。我是否忘记传递某些props或裁判?

可以在此处找到自定义 ValueContainers 的键盘导航示例:https ://codesandbox.io/s/rjvkzk1nn?from-embed

4个回答

键盘不再工作,因为您错过了Input打开Menu.

ValueContainer 当没有选择值时有两个对象:

  • Placeholder
  • Input

当您选择一个(或多个)值时,它会更改为:

  • SingleValue 或者 MultiValue
  • Input

在您之前的示例中,您正在删除这两个。

要保留键盘功能,您需要保留Input组件。以下代码是您的代码和期望的组合并保留了Input组件:

const ValueContainer = ({ children, ...props }) => {
  const { getValue, hasValue } = props;
  const newChildren = _.cloneDeep(children);
  const nbValues = getValue().length;
  newChildren[0] = `${nbValues} items selected`;

  if (!hasValue) {
    return (
      <components.ValueContainer {...props}>
        {children}
      </components.ValueContainer>
    );
  }
  return (
    <components.ValueContainer {...props}>
      {newChildren}
    </components.ValueContainer>
  );
};

const options = [
  { label: "label 1", value: 1 },
  { label: "label 2", value: 2 },
  { label: "label 3", value: 3 },
  { label: "label 4", value: 4 }
];

function App() {
  const components = { ValueContainer };
  return <Select isMulti components={components} options={options} />;
}

活生生的例子

原来你应该把自定义值容器放在渲染之外

const CustomValueContainer: React.FC = props => (
  <components.ValueContainer {...props} />
);

const App = () => {
  const [selectValue, setSelectValue] = useState();
  return (
    <div className="App">
      <Select
        options={options}
        value={selectValue}
        closeMenuOnSelect={false}
        onChange={value => setSelectValue(value)}
        components={{
          ValueContainer: CustomValueContainer,
        }}
      />
    </div>
  );
};

https://github.com/JedWatson/react-select/issues/2810#issuecomment-569117980

我的解决方案很简单,React 不会抱怨缺少keyprops并且 Web 浏览器不会挂起。

进口

import Select, { components } from 'react-select'

ValueContainer 功能

  const ValueContainer = ({ children, ...props }) => {
    const length = children[0].length
    let tmpChildren = [...children];
    if(length >= 2){
      tmpChildren[0] = `${length} languages`
    }
    return (
      <components.ValueContainer {...props}>{tmpChildren}</components.ValueContainer>
    );
  };

<Select/> 零件

<Select
      isMulti
      components={{ ValueContainer }}
      classNamePrefix="simplelocalize-select"
      placeholder="Showing all languages"
      closeMenuOnSelect={false}
/>
const ValueContainer = ({
  children,
  ...props
}: any) => {
  const currentValues = props.getValue();
  let selectedItemsLength = 0;
  let toBeRendered = children;
  if (currentValues.length >= 3) {
    toBeRendered = [children[0].slice(0, 3), children[1]];
    selectedItemsLength = currentValues.length - 3;
  }

  if (selectedItemsLength >= 1) {
    return ( <
      components.ValueContainer { ...props
      } > {
        toBeRendered
      } + {
        selectedItemsLength
      }
      selected <
      /components.ValueContainer>
    );
  }
  return ( <
    components.ValueContainer { ...props
    } > {
      toBeRendered
    } <
    /components.ValueContainer>
  );
};