Tutorial

How To Create Searchable, Async Dropdowns with React-Select

React

Introduction

HTML provides a <select> element that allows end-users to choose from a dropdown menu of <option>s. However, there may be situations where a select menu can benefit from additional user experience niceties, like allowing a user to filter available choices.

React Select is a highly configurable select menu library for React that features dynamic search and filter. It also supports async option loading, accessibility, and fast render times.

In this tutorial, you will add React Select to a project. You will also explore some of the additional features available: multi-select, user-creatable options, and async option loading.

Prerequisites

To complete this tutorial, you’ll need:

This tutorial was verified with Node v14.7.0, npm v6.14.7, react v16.13.1, and react-select v3.1.0.

Step 1 — Setting Up the Project

Start with using create-react-app to generate a React App and then install dependencies:

  • npx create-react-app react-select-example

Change into the new project directory:

  • cd react-select-example

Now, you can run the React application:

  • npm start

Fix any errors or issues with your project, then visit localhost:3000 in a web browser.

Once you have a working React application, you can start adding React Select.

Step 2 — Adding React Select

Your project will require installing the react-select library:

  • npm install react-select@3.1.0

Note: Presently, there is an issue with the latest version of the library (3.1.0), where it generates warnings for legacy and deprecated API when using StrictMode. These are known issues, and a few pending pull requests will address some of them.

Here is an example of modifying App.js to display a dropdown menu of aquatic animals:

  • nano src/App.js

Add an array for aquaticCreatures and use the Select component provided by React Select:

src/App.js
import React from 'react';
import Select from 'react-select';

const aquaticCreatures = [
  { label: 'Shark', value: 'Shark' },
  { label: 'Dolphin', value: 'Dolphin' },
  { label: 'Whale', value: 'Whale' },
  { label: 'Octopus', value: 'Octopus' },
  { label: 'Crab', value: 'Crab' },
  { label: 'Lobster', value: 'Lobster' },
];

function App() {
  return (
    <div className="App">
      <Select
        options={aquaticCreatures}
      />
    </div>
  );
}

export default App;

You will notice three things:

  • You must import the Select component from react-select.
  • Each object in the options array aquaticCreatures must have at least two values: label, a string, and value, which may be any type.
  • The only required prop is the options array.

Note: If you are populating your React Select component with an array of strings, rather than manually repeating label and value, you can use JavaScript’s map array method to prepare the options array:

someArrayOfStrings.map(opt => ({ label: opt, value: opt }));

To capture when the user selects an option, add the onChange prop:

src/App.js
<Select
  options={aquaticCreatures}
  onChange={opt => console.log(opt.label, opt.value)}
/>

The value passed to the onChange function is the same object that makes up the option itself, so it will contain the label and value variables.

Run your project:

  • npm start

Then, visit localhost:3000 in your web browser.

You will be presented with a React Select menu with aquaticCreatures:

Screenshot of React Select component with aquaticCreatures

If you interact with this menu, you will trigger an onChange event and log messages to the console. By opening your browser’s developer console, you should observe the label and value of your choices:

Output
'Shark' 'Shark'

Now that you have a working React Select menu, you can explore some of the other features this library provides.

Step 3 — Adding Advanced Options

In addition to search and selection, React Select offers other features like multi-select, user-creatable options, and async option loading.

Multi-Select

HTML <select> supports multiple to allow selecting multiple <option>s.

Similarly, in React Select, you can enable multi-select by adding the isMulti prop to your element:

src/App.js
<Select
  options={aquaticCreatures}
  isMulti
/>

For exploration purposes, the onChange prop will also need to be modified to support multi-select because opt is no longer a single object. With multi-select, it becomes a nested object. opt.label and opt.value would have otherwise returned undefined.

src/App.js
<Select
  options={aquaticCreatures}
  isMulti
  onChange={opt => console.log(opt)}
/>

Run your project:

  • npm start

Then, visit localhost:3000 in your web browser.

Select an option from the aquaticCreatures, and then select another. All of your multiple selections should be indicated by the component:

Screenshot of React Select component with Shark and Dolphin options selected

That concludes the multi-select feature.

User-Creatable Options

You can provide user-creatable options to allow users to add custom values to the select menu in situations where the choice they want is not present in the menu.

First, you need to import the Creatable component from react-select/creatable:

src/App.js
import Creatable from 'react-select/creatable';

Then, replace the Select component with Creatable:

src/App.js
<Creatable
  options={aquaticCreatures}
/>

For exploration purposes, the onChange prop will also need to be modified to display the meta value:

src/App.js
<Creatable
  options={aquaticCreatures}
  onChange={(opt, meta) => console.log(opt, meta)}
/>

Run the project:

  • npm start

When you type an option that does not currently exist—like Cuttlefish—you will be presented with a 'Create' option:

Screenshot of React Select component creating a new Cuttlefish option

After creating the new menu item, you should observe the following in your browser’s developer console output:

Output
{ label: 'Cuttlefish', value: 'Cuttlefish', __isNew__: true } { action: 'create-option' }

Notice that you have two ways of detecting that the event is a new option: the __isNew__ variable of your selected option and the action value of the meta argument in the event handler.

Also, notice how the label and value will be identical strings. Users are not provided with an option to provide a label with a different value, which may affect how you approach your solution for consistency in your data store.

That concludes the user-creatable options feature.

Async Option Loading

You can use async option loading to allow users to experience faster initial loading times in your application. This will only populate the component when the user interacts with it.

Much like the Creatable component, you will need to import AsyncSelect from react-select/async:

import AsyncSelect from 'react-select/async'

Then, replace the Select component with Async:

src/App.js
<AsyncSelect
  loadOptions={loadOptions}
/>

To load the options, pass the loadOptions prop a function, similar to the following:

const loadOptions = (inputValue, callback) => {
  // perform a request
  const requestResults = ...

  callback(requestResults)
}

React Select also supports the defaultOptions prop, which calls the loadOptions function on initialization to populate the dropdown, and the cacheOptions prop, which caches the options while its value is truthy.

That concludes the async option loading feature.

Conclusion

In this tutorial, you added React Select to a project. The customization and feature set of React Select has the potential to provide your users with a greater user experience than a standard select menu.

Additional information about the props and advanced features can be found in the React Select documentation.

If you’d like to learn more about React, take a look at our How To Code in React.js series, or check out our React topic page for exercises and programming projects.

Creative Commons License