Brady Dowling
Brady Dowling

Reputation: 5522

Order search results in react-select

When using react-select, search results are ordered alphabetically by default. This is a good default but not so nice if I have an exact match that is not first alphabetically. For example, a user may have the following options:

With these options, the user may search for 'react' and not be any closer to selecting the option that exactly matches the search term. Is there any way to optimize for exact matches?

Upvotes: 8

Views: 4923

Answers (3)

Sharud
Sharud

Reputation: 425

@ron4ex has a great answer here. Just wanted to offer another similar solution as I had 1 big issue with match-sorter.

Issue with match-sorter:

  • My list is a list of family relationships, e.g. "mother", "mother-in-law"
  • match-sorter would prioritize mother-in-law over mother as I started typing. Only once it was a full match would it prioritize mother. However, react-select kept the focused option as mother-in-law.
  • Even if I could fix the default focus issue, I would rather "mot" match to "mother" before "mother-in-law".

Enter new solution: Fuse:

  • Similar implementation as match-sorter
  • Fuzzy search with lots of customization options
  • Default config sorted "mother" over "mother-in-law"
const fuse = new Fuse(relationshipTypes, { keys: ["label"] });

<Select>
  onInputChange={inputValue => {
    setRelationshipOptions(
      fuse.search(inputValue).map(value => value.item)
    );
  }}
</Select>
  • notice the map on fuse.search as fuse returns a mutated array with the original values in an item key and a second key being the index. Hence, fuse.search().map

Upvotes: 2

ron4ex
ron4ex

Reputation: 1083

react-select has a prop if you want to have a custom filter - filterOption.

If you want to show better matches based on what a user queries, use match-sorter in combination with onInputChange of react-select to create a custom filter. Here's a working demo.

There are two select inputs. Type l and observe the difference in suggestions.

Upvotes: 10

John Ruddell
John Ruddell

Reputation: 25842

In react-select you can pass a filterOption property to change how the filtering works. They provide a nice api to do what you want, which is start matching from the beginning of the string rather than anywhere in the string. That would look something like this

filterOption={createFilter({ matchFrom: "start" })}

where createFilter is imported from react-select

Upvotes: 10

Related Questions