Categories
React

Creating Dropdown Menus with React Select

Spread the love

React Select is a dropdown menu library for React apps.

It supports many things that aren’t supported by regular dropdowns.

In this article, we’ll look at how to add menus with React Select.

Getting Started

We can install the package by running:

yarn add react-select

or:

npm i react-select

Then we can use it by writing:

import React from "react";
import Select from "react-select";

const options = [
  { value: "apple", label: "Apple" },
  { value: "orange", label: "Orange" },
  { value: "grape", label: "Grape" }
];

export default function App() {
  return (
    <>
      <Select options={options} />
    </>
  );
}

We add an options array with each entry having the value and label properties.

Then we pass that into the Select component.

Now the labels are displayed in the dropdown.

Animation

We can add animation with the makeAnimated function.

For instance, we can write:

import React from "react";
import Select from "react-select";
import makeAnimated from "react-select/animated";
const animatedComponents = makeAnimated();

const options = [
  { value: "apple", label: "Apple" },
  { value: "orange", label: "Orange" },
  { value: "grape", label: "Grape" }
];

export default function App() {
  return (
    <>
      <Select options={options} components={animatedComponents} />
    </>
  );
}

We pass the animatedComponents as the value of the components prop and we’ll see some animation.

Custom Styles

We can add custom styles with an object.

For example, we can write:

import React from "react";
import Select from "react-select";

const dot = (color = "#ccc") => ({
  alignItems: "center",
  display: "flex",

":before": {
    backgroundColor: color,
    borderRadius: 10,
    content: '" "',
    display: "block",
    marginRight: 8,
    height: 10,
    width: 10
  }
});

const styles = {
  control: styles => ({ ...styles, backgroundColor: "white" }),
  option: (styles, { data, isDisabled, isFocused, isSelected }) => {
    return {
      ...styles,
      backgroundColor: "green",
      color: "#ccc",
      cursor: isDisabled ? "not-allowed" : "default",
      ":active": {
        ...styles[":active"],
        backgroundColor: "orange"
      }
    };
  },
  input: styles => ({ ...styles, ...dot() }),
  placeholder: styles => ({ ...styles, ...dot() }),
  singleValue: (styles, { data }) => ({ ...styles, ...dot(data.color) })
};

const options = [
  { value: "apple", label: "Apple" },
  { value: "orange", label: "Orange" },
  { value: "grape", label: "Grape" }
];

export default function App() {
  return (
    <>
      <Select options={options} styles={styles} />
    </>
  );
}

We create a dot function that returns an object with some styles for a dot.

The :before has everything that creates a dot to the left of the text.

styles has various properties for the controls, options, input, placeholder, and selected values.

We can style according to the isFocused property which indicates whether the choice is in focus.

isSelected indicates whether the choice is selected.

data is the data of the item.

We then pass all that into the styles prop.

Multiselect

We can enable multiple selection with the isMulti prop.

For instance, we can write:

import React from "react";
import Select from "react-select";

const options = [
  { value: "apple", label: "Apple" },
  { value: "orange", label: "Orange" },
  { value: "grape", label: "Grape" }
];

export default function App() {
  return (
    <>
      <Select options={options} isMulti />
    </>
  );
}

Now we can pick multiple choices from the list.

Loading Choices Asynchronously

We can load choices in an async manner.

To do that, we use the AsyncSelect component:

import React from "react";
import AsyncSelect from "react-select/async";

const options = [
  { value: "apple", label: "Apple" },
  { value: "orange", label: "Orange" },
  { value: "grape", label: "Grape" }
];

const filterOptions = inputValue => {
  return options.filter(i =>
    i.label.toLowerCase().includes(inputValue.toLowerCase())
  );
};

const loadOptions = (inputValue, callback) => {
  setTimeout(() => {
    callback(filterOptions(inputValue));
  }, 1000);
};

export default function App() {
  const [inputValue, setInputValue] = React.useState("");
  const handleInputChange = newValue => {
    const inputValue = newValue.replace(/W/g, "");
    setInputValue(inputValue);
    return inputValue;
  };

  return (
    <div>
      <pre>inputValue: "{inputValue}"</pre>
      <AsyncSelect
        cacheOptions
        loadOptions={loadOptions}
        defaultOptions
        onInputChange={handleInputChange}
      />
    </div>
  );
}

We gave the filterOptions method to filter by the value.

loadOptions lets us load the options asynchronously.

It has the inputValue parameter which will be passed in when we type in something.

In the App component, we set the inputValue with the input box.

Also, we have the cacheOptions to cache the options.

defaultOptions determines when the request for the options is fired.

Conclusion

We can create a dropdown easily with React Select.

We can create a dropdown that supports multiple selections, styling, and async loading of options.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *