In v1 overriding the standard filterOptions meant that you could return the options in a completely different order based on the search, whereas the new filterOption is only giving us the option to specify if that option should be shown or not.
I think that having some way of ordering the results is useful in lots of cases. Here's one with some dummy data. Let's suppose that my options is a long list of names and we expect that someone will probably start typing the person's first name in order to get to that person as quickly as possible, but they might also only know a surname.
If we have the following names at the start of the options, "Alexa Nabil", "Alexandra Bilani", "Bill Ward" and the user starts typing "Bi" then currently the default behaviour of react-select is to show the options in their original, alphabetical order, but I'd suggest that "Bill Ward", "Alexandra Bilani", "Alexa Nabil" makes more sense once there's the user input. That's possible with filterOptions because you can sort the options at the same time as filtering them, but v2 leaves me without a way of doing this.
Meanwhile i had to do something like this:
class CustomIput extends Component {
constructor(props) {
super(props);
this.state = {
dynamicOptions: [],
};
}
handleInputChange = (value, { action }) => {
if (action === 'input-change') {
// custom logic like sorting or slicing the options array.
this.setState({ dynamicOptions });
}
}
render() {
return (
<Select
options={this.state.dynamicOptions}
onInputChange={this.handleInputChange}
filterOption={() => true}
/>
);
}
}
Hope it helps someone
It sounds like we need a companion function for filterOption -- sortOptions, with the shape of:
(OptionType, OptionType) => 0 | -1 | 1
@nenostra Thank you for your solution. It works pretty well. I didn't expect filterOption={() => true} stop the react-select input filtering
Another issue with current filterOption is that it repeats preprocessing of inputValue for each option. (In case of the default filter, it invokes trimString > toLowerCase > stripDiacritics on inputValue.)
What about this theme? Any updates?
I'd love for this to become a first class part of the API
A new version slightly improved inspired in the version by @nenostra
You can take this component and just use it instead of <Select/>
import React, { useState, useEffect } from 'react';
import Select from 'react-select';
import matchSorter from 'match-sorter'
const MatchSortSelect = React.forwardRef((props, ref) => {
let [options, setOptions] = useState(props.options);
useEffect(() => {
setOptions(props.options);
}, [props.options]);
const onInputChange = (value, { action }) => {
if (action === 'input-change') {
let filteredOptions = matchSorter(props.options, value, { keys: ['label']});
setOptions(filteredOptions);
} else if (action === 'menu-close') {
setOptions(props.options);
}
}
return <Select
{...props}
ref={ref}
filterOption={false}
onInputChange={onInputChange}
options={options}
/>
});
export default MatchSortSelect;
Most helpful comment
Meanwhile i had to do something like this:
Hope it helps someone