5 Most Common Dropdown Use Cases Solved with React Downshift

Downshift is a library that helps you build simple, flexible, WAI-ARIA compliant enhanced input React components. Its major use case is for building autocomplete components but it can also be used to build dropdown components.
In this post, we’ll walk through some common use cases solved with Downshift.

To follow this tutorial, you need Node and NPM installed on your machine. A basic understanding of React will help you get the most out of this tutorial.
If you don’t have Node.js installed, go to the Node website and install the recommended version for your operating system.

Table of Contents

We’ll make use of Create React App to create a simple React app with no build configuration. If you don’t have Create React App installed, run npm i create-react-app in your terminal to install it.
Once you have it on your machine, run the following command to set up a new React project in a directory called downshift-examples and move to this new directory by running these commands:

$ create-react-app downshift-examples
$ cd downshift-examples

Once you’re in the downshift-examples directory, run the following command to install Downshift and some other packages:

In the code above, we import React and Downshift and declare an array of books, an onChange function and also a functional component which returns the <Downshift/> component. In the <Downshift/> component, we pass the onChange and itemToString props. Inside the <Downshift/> component, we’ll pass other props to a callback and render our input field.

Next, we’ll pass the props we need in a callback to the <Downshift/> component. Update your functional component with the following:

In the callback, we add our input tag and pass it our getInputProps props:

<input {...getInputProps({ placeholder: "Search books" })} />

Next, we check if the input element is open. If it is, we return a div element containing our menu and return null if it’s not:

{ isOpen ? (<div className="downshift-dropdown">...</div>) : null }

Lastly, in the div element which we’re returning, we basically filter through our books array, returning only the items that include the inputValue. We then map through the filtered books and render them on the page.
Note that we passed the getItemProps function to the div rendered in the map function. It returns the props that we applied while rendering the items.

In the code above, we have a class component where we’re rendering the <Downshift/> component and passing our props to it. In the input field in the <Downshift/> component, we have an onChange event listener that listens for new input to the field.
If there’s an input, we call the fetchMovies method which takes the value of the input field and makes an AJAX request to the movies API using Axios. We set the request response to the component state, then filter through them to return the matching item as done in the previous example.

Import and render the component in the parent App component as we did in the previous example. Visit your browser and try searching for your favorite movie:

One other use case for Downshift is powering dropdowns. Dropdown’s API helps us build simple dropdown components. Let’s create a DownshiftThree.js file in the src folder and see how to achieve this.
In the DownshiftThree.js file, add the following code:

In the code above, we have a DownshiftThree class component where we render the <Downshift/> component. In the callback passed to it, we have a button where we pass the getToggleButtonProps function. The button houses a ternary operator where we set the content the button based on whether the selectedBook in the component’s state is set.
Next, we call the isOpen prop to see if the dropdown is open or not. If it is open, we map through all the books and render them in the dropdown.

In the onChange method passed to the <Downshift/> component, whenever an item is selected, we set it the state, thereby updating the content of the button.
Import and render the component to the parent App component and reload your browser. You should see something like this:

In this example, we’ll be using a Downshift input component as input fields in a form and attempting to submit the form data. In the src directory, let’s create two files: DownshiftInputField.js and DownshiftFour.js.

In the DownshiftInputField.js, we’ll create an input component with Downshift and use it to render some input fields in the DownshiftFour.js file. Let’s create a functional component in our DownshiftInputField.js file:

In the code above, our functional component takes in an array of items, an onChange function, a label and placeholder text and finally a name. The component returns a <Downshift/> component which receives all the required props in a callback function. In the callback, we have a label and an input field.
As with other examples, we pass the isOpen prop to a ternary operator. If the input field is open, we filter through the array of items to return items that match the inputValue , then we map through the returned items and render them to the DOM.

Now that our input field component is ready, let’s import it into the DownshiftFour.js file:

In our DownshiftFour.js file, we imported our input field component and created a class component. In our component state, we have an array of books and movies and we render our input field component twice in a form: one as an input field for books and another for movies.

Downshift’s onChange function takes in a second parameter called stateAndHelpers which gives us some information about Downshift’s current state.
In the onChange method, we find the input field the user is currently interacting with by getting it’s id from the stateAndHelpers argument and querying the DOM for it. Once we have the element, we set it to the component state.

When the user hits the submit button, the onSubmit method, gets the selected book and movie from the state and does whatever we want with it.

Import and render the <DownshiftFour/> component in the parent App component and let’s give it a spin in the browser. You should have something similar to this:

In our last example for this article, we’ll be using Popper.js to change the directions of a Downshift popup. Popper is an awesome library that makes positioning tooltips or popups a straightforward
task. We already installed the react-popper package while setting up the application, so let’s create a DownshiftFive.js file in the src folder.
Let’s add the following code to the new file:

In the code snippet above, we create a DownshiftFive class components with a default position props. These are the positions Popper will use to render our popup. In the render method of the component, we’re returning a <Downshift/> component wrapped in a <Manager/> component:

The Manager component is a wrapper exposed by Popper that needs to surround all other react-popper components on the page to make them communicate with each other.
If you look closely, you’ll see we’re passing a render prop to the <Downshift/> component. This is another way to pass our props to the <Downshift/> component. Basically, we moved our callback and passed it to the render prop.
In the callback passed to the render prop, we wrap our input field in a <Target/> component. This informs Popper that this is the input field around which the popup should be rendered.

Next, we check if our input is open and render a <Popper/> component and pass our selectedItem to it’s placement prop. This helps Popper reposition the popup whenever a new position is selected. Lastly, as with other examples, we filter all the default prop positions, return the positions that include the inputValue, map through them and render them on the page.

Finally, import and render the <DownshiftFive/> component in the parent App component and check it out in the browser. You should have something similar to this:

Jobs!

If you’re familiar with popular JavaScript frontend frameworks like React, Angular, etc, then the concept of ECMAScript won’t be entirely new to you. ES Modules have the import and export syntax we see often in frontend frameworks. Node uses CommonJS which re...