如何设置可以在 react-select 中选择的最大项目数?
Posted
技术标签:
【中文标题】如何设置可以在 react-select 中选择的最大项目数?【英文标题】:How to set max number of items that can be selected in react-select? 【发布时间】:2019-08-02 18:52:00 【问题描述】:我正在使用 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
/>
【问题讨论】:
通过将此逻辑添加到onChange
处理程序。只需选择前五个即可。
什么意思?你能更精确或显示代码吗?
假设您的处理程序每次更改时都会收到新的选择,我猜处理程序的参数将是选择作为数组。然后在调用setState(() => ( multi: selectionArray.slice(4) ))
时对这个数组进行切片。
或者,您可以对数组的末尾进行切片以获得最新的选择,这取决于结果如何传递给处理程序。
【参考方案1】:
我发现了一种更简单、更干净的方式,无需额外的操作。
这种方式基于禁用“react-select”的输入组件。
仔细看看参数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;
因此您无需管理多余的组件。
【讨论】:
【参考方案2】:一个非常简单的方法是:
<Select
value=tags
onChange=(v) => v.length < 4 ? setTags(v): null
isMulti
name='tags'
options=options
className='basic-multi-select'
classNamePrefix='select'
/>
只需添加一个简单的三元检查来检查您想要多少项目
【讨论】:
【参考方案3】:我正在分享我认为它可以提供帮助的完整工作组件>>
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】:有关如何解决此问题的主要文档可在此处找到:
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
/>
)
【讨论】:
请添加一些关于您的代码的解释,它的作用以及它是如何做的并回答问题【参考方案5】:就我而言,我使用了来自 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: []
【讨论】:
【参考方案6】:<CreatableSelect
classes=classes
styles=selectStyles
options=this.state.multi.length > 4 ? this.state.multi : suggestions
components=Components
value=this.state.multi
placeholder="Tags"
onChange=(values) => this.setState( multi: values )
isValidNewOption=isValidNewOption //Look at Marked Answer
isMulti
/>
【讨论】:
添加对options
的检查并仅在低于限制时才设置数据是完整的解决方案。【参考方案7】:
我建议您使用自定义组件Menu
和isValidNewOption
的组合,如以下代码:
// 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),并防止通过 isValidNewOption
属性创建时的 enter
键盘事件。
【讨论】:
非常感谢。它帮助我解决了我的问题。 如果您手动输入另一个选项并按 Enter,或者您输入并按 Tab 键,这将不起作用 - 这将允许输入超过定义的限制。 无论有没有isValidNewOption
tbh,我都看不出有什么不同
@nickornotto 如果您不使用isValidNewOption
,您仍然会看到Max limit achieved
,但是如果您开始输入与任何选项都不匹配的文本,您将能够创建一个新选项并超过限制
好的,谢谢,我只在Select
上尝试过,Creatable
上有意义以上是关于如何设置可以在 react-select 中选择的最大项目数?的主要内容,如果未能解决你的问题,请参考以下文章