DEV Community

Brian Neville-O'Neill
Brian Neville-O'Neill

Posted on • Originally published at blog.logrocket.com on

Getting started with react-select

Introduction

Building select elements used to be one of the easiest things to build when working on a web project three or four years ago. Now, there is so much that goes into building select elements especially when UI/UX is a high priority.

One has to consider features such as on-focus, styling select elements, fetching data from a remote source and the list goes on. You may have had this thought when working on that React project and wished a reusable component existed somewhere in the multiverse. Well, lucky for us, Jed Watson started an open source project, funded by Thinkmill (his company) and Atlassian, called react-select.

There were several limitations with version one of react-select, which gave birth to v2. In this article, we’ll be going over the awesome features embodied in react-select v2 as well as getting on a launchpad to introduce us to react-select v2 and how to get started.

Installation and basic usage

Prerequisites

  1. Yarn/npm installed
  2. create react app CLI tool installed
  3. A basic understanding of HTML, JavaScript (ES6) and CSS
  4. A basic understanding of React JS and using create react app
  5. A basic understanding of the command line terminal

LogRocket Free Trial Banner

Installation

With all of those requirements out of the way, it’s time for us add the react-select package to our existing React application. For the sake of this tutorial, we’ll be using the create react-app CLI tool. If you don’t already have an existing project you can provision one like this:

$ yarn create react-app react
Enter fullscreen mode Exit fullscreen mode

After that is done, we’ll install the react-select package from npm:

$ yarn add react-select
Enter fullscreen mode Exit fullscreen mode

Now, we’ll take a look at how we can import and use the react-select package in a react application.

Basic usage

In theApp.js file, we import two items at the top of the file, the react and react-select package respectively like this:

//App.js

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

...
Enter fullscreen mode Exit fullscreen mode

With those two packages imported, we will be able to have access to the react-select ( ) and also extend the React.Component class. In traditional HTML, the tag houses multiple options and values. Our react-select component follows the same convention but the options and values are passed in as props.

//App.js

//Import React and Select 

const options = [
  { value: 'blues', label: 'Blues' },
  { value: 'rock', label: 'Rock' },
  { value: 'jazz', label: 'Jazz' },
  { value: 'orchestra' label: 'Orchestra' } 
];

class App extends React.Component {
  render(){
    return (
      <Select options = {options} />
    );
  }
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In the code snippet above, we have our select options as music genres which is passed into the select component as props. The class App is exported so that it could be rendered to our App component in the DOM. When we run this application we should see a select element that spans across the screen from one end to the other.

a select element that spans across the screenIf you got that output when you ran your react application, kudos. In the coming sections, we’ll look at how we can style the select component to extend its functionalities and make it visually pleasing.

Custom styling your select components

In this section, we’ll be discussing how we can add beauty and aesthetics to our select component. First things first, we will leverage bootstrap CSS to resize our select component so it doesn’t take up the whole width of the web page. We’ll install bootstrap in our project like so:

$ yarn add boostrap@4.31
Enter fullscreen mode Exit fullscreen mode

With bootstrap installed, we’ll add our styling to our select component.

//App.js

import 'bootstrap/dist/css/bootstrap.css';
//Import react and select 

return(
  <Select className="mt-4 col-md-8 col-offset-4"
    options = { options }
  />
);

...
Enter fullscreen mode Exit fullscreen mode

For better results, we’ll enclose our root DOM element in index.html in a bootstrap container.

<!-- index.html -->
...

<div class="container">
    <div id="root"></div>
</div>

...
Enter fullscreen mode Exit fullscreen mode

This will give us a select element that looks exactly like the image below:

Styles and states

In this section, we will look at how we can extend the out-of-the-box default styling, and also look at how we can style the entire component. The code block above where we added some bootstrap styling is a good demonstration of extending the default styling which comes with the select component. To elaborate further we will tweak the look and feel of the select component:

//App.js 
//Import react and select

const customStyles = {
  option: (provided, state) => ({
    ...provided,
    borderBottom: '2px dotted green',
    color: state.isSelected ? 'yellow' : 'black',
    backgroundColor: state.isSelected ? 'green' : 'white'
  }),
  control: (provided) => ({
    ...provided,
    marginTop: "5%",
  })
}

...

return(
  <Select className="col-md-8 col-offset-4"
    styles = { customStyles }
    options = { options }
  />
);

...
Enter fullscreen mode Exit fullscreen mode

There are two component properties (option and control) we tweaked to extend and customize the look and feel of the select component. There are many properties provided by react-select which gives us, the consumers, a lot of room to build to our needs and taste. We will discuss custom components in detail in a later section of this article. For the sake of this section, we will briefly discuss the two custom components stated above.

Option: This is the component responsible for displaying the options. By targeting this component we were able to get the select element below:

In the image above we were able to set the background of a selected option to green and change the text color to yellow. This was made possible by extending its default styling by spreading it into the provided variable …provided

Control: This is the component responsible for the ValueContainer and IndicatorsContainer . With this, we were able to add a margin-top property of 5% which moved the whole select component away from the top of the page as shown in the image above as opposed to the very first image of the select component in the basic usage section.

Props

In this section, we will take a look at some of the major props we use to customize the functionalities of our select component. Below is an example of how some of these props come in handy.

//App.js

//Import react and select

state = {
  selectedOption: null,
}
handleChange = (selectedOption) => {
  this.setState({ selectedOption });
  console.log(`Option selected:`, selectedOption);
}
render(){
  const { selectedOption } = this.state;
}

return (
  <Select className="mt-4 col-md-6 col-offset-4"
  onChange={this.handleChange}
  options={options}
  autoFocus={true}
  />
)
Enter fullscreen mode Exit fullscreen mode

Above is the state manager prop onChange which we use to get the information about the currently select item. Supposing we select rock as an option in our console we’ll get something along the lines of Option selected: {value:"rock", label: "Rock"} this will come in handy when we want to manipulate the data gotten from our select component. Other props seen are the options and autoFocus props. The options prop is used to pass in select options to the select component. The options used in the code block above are:

const options = [
  { value: 'blues', label: 'Blues' },
  { value: 'rock', label: 'Rock' },
  { value: 'jazz', label: 'Jazz' },
  { value: 'orchestra' label: 'Orchestra' } 
];
Enter fullscreen mode Exit fullscreen mode

The autoFocus prop which has a data type of boolean is used to add autoFocus to the select component on page load. To know about props which are available for use you can check out the props documentation for react-select.

Custom components

Under styles and states , we discussed two custom components (option and control) which we used to extend the select styling. In this section, we’ll take a look at another custom component called the Custom SingleValue . This custom component does what our regular select component does but we’re going to add a little bit of finesse. In our App.js file, we’ll import the React and Select packages from react and react-select respectively like so:

//App.js

import React, { type ElementConfig } from 'react';
import Select, { components } from 'react-select';
...
Enter fullscreen mode Exit fullscreen mode

By the time we are done, we have a finished product that looks something like this:

In the code block below, we define our custom component SingleValue as a method which extends the base component in the react-select package. In our App class, we have a couple of props and functions which contribute to the functionality (as shown in the image above) such as:

handleChange: This method is triggered by a state manager prop called the onChange . This method is responsible for storing the value of the selected option in our state object called selectedOption

styles: In this prop, we extend the style modifier method singleValue where we modify the styling already accessible to us by default by spreading default styles into the base object. The line responsible for adding a background color to each selected option is the background: this.state.selectedOption.value where we get the current option selected from the state and use it to update the background

components: In the component prop we pass in the SingleValue component, the primary function of the component is to display in the input for a single select.

options: The options prop that we all know by now is how we pass in our array object of select items which in this case are colors like so.

className: In this prop is where we add our bootstrap styling to position our select component away from the top margin as well as centralize our select component nicely.

//App.js 

 const SingleValue = ({ children, ...props }) => (
   <components.SingleValue {...props}>
     {children}
   </components.SingleValue>
 );

 class App extends React.Component {
   state = {};
   state = {
     selectedOption: null,
   }
   handleChange = (selectedOption) => {
     this.setState({ selectedOption });
   }
   render() {
     return (
       <Select
           className="mt-4 col-md-6 col-offset-4"
           onChange={this.handleChange}
           styles={{ singleValue: (base) => ({ ...base, padding: 5, borderRadius: 5, background: this.state.selectedOption.value, color: 'white', display: 'flex' }) }}
           components={{ SingleValue }}
           options={colourOptions}
         />
     );
   }
 }
 export default App;
Enter fullscreen mode Exit fullscreen mode

Using built-in animated components

In this section, we will take a look at how we can add a little animation to our react select component. All we need to add animation to our select component is to import the animated component which in this case is named makeAnimated and then reference makeAnimated in our component’s props like so:

//App.js

import React from 'react';
import Select, { components } from 'react-select';
import makeAnimated from 'react-select/lib/animated';
import 'bootstrap/dist/css/bootstrap.css';

const colourOptions = [] //our array of colours

class App extends React.Component {
  render(){
    return (
      <Select
        className="mt-4 col-md-6 col-offset-4"
        components={makeAnimated()}
        isMulti
        options={colourOptions}
        />
    );
  }
}

export default App;
Enter fullscreen mode Exit fullscreen mode

TheisMulti prop is used to make us select more than one option at once as we can see in the gif below:

Other concepts

There are other concepts which are important to know in regards to working with the react-select component. One of which is theAsync component which is imported like this:

import Async from 'react-select/lib/Async';
Enter fullscreen mode Exit fullscreen mode

This component comes in handy when we want to request our select values or options from an API or a database query. This component helps to add Async property to our select component which comes bootstrapped with helper props such as

cacheOptions for caching options and also an event listener props onInputChange.This component can be implemented through the use of callbacks or promises.

Another component which may come in handy is the fixed options component. This component makes it possible to have fixed options as already selected values which can’t be removed.

Conclusion

In the course of this article, we have learned some common use cases of the react-select component, how to get started and also how to extend some of the predefined components to suit our needs. There are a plethora of functionalities built into the react-select package, some of which will fit your needs, some of which you’ll need to customize to fit your use case. Here’s a link to the official documentation to get your hands dirty. Feel free to leave a comment if you have questions or get stuck I’ll lend a helping hand. 😎


Plug: LogRocket, a DVR for web apps

 
LogRocket Dashboard Free Trial Banner
 
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
Try it for free.


The post Getting started with react-select appeared first on LogRocket Blog.

Top comments (3)

Collapse
 
dance2die profile image
Sung M. Kim

Thank you for the recent posts, Brian.

I've noticed that formatting/syntax highlights seem to be off for many posts.

Would you be able to update them?

Collapse
 
bnevilleoneill profile image
Brian Neville-O'Neill

I've noticed that too. I'm going to look into it. I think what's happening is porting stuff over from WordPress to here is messing with the formatting. The formatting on blog.logrocket.com should be correct - but viewing the post there is totally up to you. Thanks!

Collapse
 
dance2die profile image
Sung M. Kim

Ah, LogRocket blog is using Mediumish theme for WordPress.

I've had some trouble with code snippets and emojis when importing from my WordPress site.

So ended up using Gists & fixing emojis manually 😓