如何设置可在react-select中选择的最大项目数?

时间:2019-03-12 10:21:31

标签: javascript reactjs jsx react-select

我正在使用react-select中的CreatableSelect组件。现在,用户可以选择任意数量的项目,但我希望用户选择的项目不超过5个。如何限制可以选择的最大选项数量?

<CreatableSelect
  classes={classes}
  styles={selectStyles}
  textFieldProps={{
    label: "Tags"
  }}
  options={suggestions}
  components={components}
  value={this.state.multi}
  onChange={this.handleChange("multi")}
  placeholder=""
  isMulti
/>

6 个答案:

答案 0 :(得分:1)

我建议您使用自定义组件MenuisValidNewOption的组合,例如以下代码:

// For this example the limite will be 5
    const Menu = props => {
      const optionSelectedLength = props.getValue().length || 0;
      return (
        <components.Menu {...props}>
          {optionSelectedLength < 5 ? (
            props.children
          ) : (
            <div>Max limit achieved</div>
          )}
        </components.Menu>
      );
    };

    function App() {
      const isValidNewOption = (inputValue, selectValue) =>
        inputValue.length > 0 && selectValue.length < 5;
      return (
        <div className="App">
          <Creatable
            components={{ Menu }}
            isMulti
            isValidNewOption={isValidNewOption}
            options={options}
          />
        </div>
      );
    }

这里是live example

这个想法是为了防止用户在限制X(在示例中为5)之后访问选项,并防止通过enter属性创建时发生isValidNewOption键盘事件。

答案 1 :(得分:0)

对于我来说,我使用了来自react-select的常规 Select 组件。

<Select 
     options={industries}
     value={industry}
     getOptionLabel={ x => x.id}
     getOptionValue={ x => x.industry}
     onChange={(e) => this.handleSelectChange(e, "industry")}
     isMulti
/>

和handleSelectChange-

handleSelectChange = (e, name) => {
    console.log(e)
    if(e.length < 6){
        return this.setState({
            [name]: e
        })
    }
}

和状态-

this.state = { industry: [] }

答案 2 :(得分:0)

有关如何解决此问题的主要文档,可以在这里找到:

https://github.com/JedWatson/react-select/issues/1341

const MultiCreatable = ({ options, handleChange, handleCreate, value, maxOptions }) => {
  return (
    <CreatableSelect
      isMulti
      placeholder={placeholder}
      onChange={handleChange}
      options={value.length === maxOptions ? [] : options}
      noOptionsMessage={() => {
        return value.length === maxOptions ? 'You have reached the max options value' : 'No options available' ;
      }}
      onCreateOption={handleCreate}
      value={value}
    />
  )
}

答案 3 :(得分:0)

我正在分享我的完整工作组件,我认为它会有所帮助>>

import React, { useState } from 'react';
import Select from 'react-select';
import makeAnimated from 'react-select/animated';
const animatedComponents = makeAnimated();

const ReactSelect = ({ data }) => {
    const maxOptions = 5;
    const [selectedOption, setSelectedOption] = useState([]);
    const handleTypeSelect = e => {
        setSelectedOption(e);
    };

    return (
        <Select
            onChange={handleTypeSelect}
            getOptionLabel={x => x.name}
            getOptionValue={x => x.slug}
            components={animatedComponents}
            isMulti
            options={selectedOption.length === maxOptions ? [] : data}
            noOptionsMessage={() => {
                return selectedOption.length === maxOptions
                    ? 'You have reached the max options value'
                    : 'No options available';
            }}
            label='tags'
        />
    );
};

export default ReactSelect;

答案 4 :(得分:0)

一个非常简单的方法是:

<Select
        value={tags}
        onChange={(v) => v.length < 4 ? setTags(v): null}
        isMulti
        name='tags'
        options={options}
        className='basic-multi-select'
        classNamePrefix='select'
      />

只需添加一个简单的三元检查您想要多少项目

答案 5 :(得分:0)

我发现了更简单和干净的方法,无需额外的操作。 这种方式基于禁用“反应选择”的输入组件。 仔细看看参数 inputProps

它看起来像:

import Select from 'react-select';
import useField from 'client/components/hooks/useField';

const MultiSelect = ({
  async,
  creatable,
  maxItems,
  ...restProps,
}) => {
  const selectProps = {
    ...restProps,
    // "inputProps: {disabled: boolean}" - our goal
    ...(typeof maxItems === 'number' && maxItems === restProps.value?.length ? {inputProps: {disabled: true}} : {}) 
  };
  const creatableTag = async ? Select.CreatableAsync : Select.Creatable;
  const SelectTag = creatable ? creatableTag : selectTag;

  return (
    <div>
      <SelectTag {...selectProps} />
    </div>
  );
};

const SomeComponentWithMultiSelect = () => {
  const field = useField('data.name'); // field contains: {value: string[], ...}
  const items = [
    {
      label: 'firstValue',
      value: 1,
    },
    {
      label: 'secondValue',
      value: 2,
    },
  ];

  return (
    <MultiSelect
      items={items}
      {...field}
      creatable
      maxItems={1} // {1} as our limit
    />
  )
};

export default SomeComponentWithMultiSelect;

因此您无需管理多余的组件。