How to Build a React Multi-Select Component

Working on a React project in the USA, I often need to give users the option to select multiple values from a list. Whether it’s choosing states, filtering product categories, or selecting skills in a job application form, a multi-select dropdown is one of the most practical components I’ve built and reused over the years.

When I first started, I struggled to find a simple, reusable solution. Most tutorials were either too complex or skipped important details. After building these components for more than a decade, I’ve figured out a few reliable methods that work in real-world projects.

In this tutorial, I’ll show you three ways to build a React multi-select component:

  1. Creating it from scratch with React hooks.
  2. Using the popular React-Select library.
  3. Building a Tailwind CSS styled multi-select.

Each method includes full code and a short explanation so you can copy, paste, and adapt it quickly.

Method 1 – Build a Multi-Select Dropdown from Scratch (React Hooks)

When I don’t want to add extra dependencies, I build the dropdown from scratch. It’s lightweight and customizable.

Here’s the complete code:

import React, { useState } from "react";

const MultiSelect = ({ options }) => {
  const [selected, setSelected] = useState([]);

  const toggleOption = (option) => {
    if (selected.includes(option)) {
      setSelected(selected.filter((item) => item !== option));
    } else {
      setSelected([...selected, option]);
    }
  };

  return (
    <div style={{ width: "250px", border: "1px solid #ccc", padding: "10px" }}>
      <div style={{ marginBottom: "10px" }}>
        Selected: {selected.length > 0 ? selected.join(", ") : "None"}
      </div>
      <ul style={{ listStyle: "none", padding: 0 }}>
        {options.map((option) => (
          <li key={option}>
            <label>
              <input
                type="checkbox"
                checked={selected.includes(option)}
                onChange={() => toggleOption(option)}
              />
              {option}
            </label>
          </li>
        ))}
      </ul>
    </div>
  );
};

// Example usage
export default function App() {
  const states = ["California", "Texas", "Florida", "New York", "Illinois"];
  return (
    <div style={{ padding: "20px" }}>
      <h2>Choose States</h2>
      <MultiSelect options={states} />
    </div>
  );
}

You can refer to the screenshot below to see the output.

Build a React Multi-Select Component

This method uses checkboxes and React’s useState hook to manage selections. It’s simple, dependency-free, and works well for small projects.

Method 2 – Use react-select (Best for Production)

In real-world applications, I often use the React-Select library. It’s powerful, customizable, and has built-in support for multi-select.

Here’s the code:

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

export default function App() {
  const options = [
    { value: "california", label: "California" },
    { value: "texas", label: "Texas" },
    { value: "florida", label: "Florida" },
    { value: "newyork", label: "New York" },
    { value: "illinois", label: "Illinois" },
  ];

  const handleChange = (selectedOptions) => {
    console.log("Selected:", selectedOptions);
  };

  return (
    <div style={{ width: "300px", margin: "20px auto" }}>
      <h2>Select States</h2>
      <Select
        options={options}
        isMulti
        onChange={handleChange}
        placeholder="Choose states..."
      />
    </div>
  );
}

You can refer to the screenshot below to see the output.

How to Build a React Multi-Select Component

With react-select, you get search, keyboard navigation, and async loading out of the box. This is my go-to choice for large-scale apps.

Method 3 – Multi-Select with React + Tailwind CSS

Sometimes, I need a fully styled component that matches a Tailwind-based design system. Here’s a Tailwind version:

import React, { useState } from "react";

const TailwindMultiSelect = ({ options }) => {
  const [selected, setSelected] = useState([]);

  const toggleOption = (option) => {
    if (selected.includes(option)) {
      setSelected(selected.filter((item) => item !== option));
    } else {
      setSelected([...selected, option]);
    }
  };

  return (
    <div className="w-72 border rounded p-3 bg-white shadow-md">
      <div className="mb-2 text-sm font-medium text-gray-700">
        Selected: {selected.length > 0 ? selected.join(", ") : "None"}
      </div>
      <ul className="space-y-2">
        {options.map((option) => (
          <li key={option}>
            <label className="flex items-center space-x-2">
              <input
                type="checkbox"
                checked={selected.includes(option)}
                onChange={() => toggleOption(option)}
                className="form-checkbox text-blue-600"
              />
              <span>{option}</span>
            </label>
          </li>
        ))}
      </ul>
    </div>
  );
};

// Example usage
export default function App() {
  const skills = ["JavaScript", "React", "Node.js", "Python", "SQL"];
  return (
    <div className="flex justify-center mt-10">
      <TailwindMultiSelect options={skills} />
    </div>
  );
}

This Tailwind version looks modern and integrates seamlessly with utility-first CSS workflows. It’s great for dashboards and admin panels.

When to Use Each Method

  • Scratch (Method 1): Perfect for small apps or when you want full control.
  • React-Select (Method 2): Best for production apps where you need search, async, and advanced features.
  • Tailwind (Method 3): Ideal when you already use Tailwind and want a styled, lightweight solution.

Building a multi-select component in React doesn’t have to be complicated. I’ve shown you three methods that I personally use, depending on the project requirements.

If you want something quick and dependency-free, go with the custom checkbox method. If you’re building a large-scale application, React-Select is the most reliable option. And if you’re working with Tailwind, the styled version fits perfectly into your design system.

Whichever method you choose, you’ll have a reusable, scalable component that makes your forms more user-friendly.

You can also read:

Leave a Comment

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.