Customizing Reusable React-Select menu & options components.

Juliet Onyekaoha
6 min readSep 4, 2020

--

In a couple react projects I have worked on at work, we used the react-select library for our select field dropdowns, mainly because it provides us with a pre-built dropdown component that is aesthetically pleasing, high performant and easy to integrate (or so I thought) across multiple applications.

However, I was recently tasked with placing a button to the bottom of the dropdown menu, which was supposed to be visible when the dropdown options are displayed. (see image below)

react-select with button
react-select with button task

After a day & half of digging through Google, the official react-select-documentation, what seemed like a thousand codesandboxes, breaking my version of the project (I had to upgrade the react-select version and painfully make changes to each of the numerous dropdowns in the application) I was able to deliver the UI Designer’s expectation. Hence I deemed it fit to write an article that might save another Front-End engineer the stress of going through that process.

Prerequisites

In this article I will presume:

  • You have a basic knowledge of React
  • Your current version of react-select is from 2.0.0 upwards.

What we are building

We will be building a select component that includes a custom menu and option component using the react-select library.

react-select custom component to build
react-select component to build

Implementation

To start replicating the steps below, you can use a codesandbox or any editor of your choice and install create-react-app. If you’re just interested in only the codes and no extra talk, just fork this codesandbox or Github repo. I have also included links to them at the end of the article.

STEP 1: Add react-select as a dependency (npm install react-select or yarn add react-select)

STEP 2: Create a folder for your custom react-select component (for this article we will call it custom-select-menu). Include custom-select.jsx , data.jsxand index.css files inside the folder.

STEP 3: Import React, react-select, index.css into your custom-select.jsx file. For the react-select import, we would be destructing the components property on the Select object. (The component property is key to customizing any component exposed by the react-select library. See the replacing components documentation for more details).

STEP 4: Inside custom-select.jsxCreate a functional component named CustomSelect and render Select in the component.

CustomSelect functional component with rendered Select

STEP 5: Import the CustomSelect component into the component you want it in and render it. Here we would import it into App.js.

render CustomSelect component in app.js

Right now, we see the select component rendered without any functionality because data has not been passed to it yet.

rendered Customselect component

STEP 6: Create a file to hold our data. For this article, I have added a file named data.jsx inside the custom-select-menu folder. Inside it is the stateOptions array below.

STEP 7: Feed react-select options property with some data to display. Because we want our component to be reusable, we will be passing the options property that is supplied by react-select as a prop, which we would reference in App.js.

pass options as prop

Import the stateOptions array into app.js and pass it as the value for the data variable in state, then inside the render function destructure data from state and assign it as a value to the options prop.

pass stateOpitons as value for options prop in app.jsx

Right now Our select component is functional and returns a drop-down list of the data in the stateOptions array.

STEP 8: To now customize the select component to how we want it to look and add a custom button at the bottom of the menu, we will create a functional menu component and pass it as a value to the components prop provided by react-select.

custom menu component
pass menu component as value to component’s props

Things to note:

  • <compents.Menu {...props}> is a way to tell the react-select library that we want to create a custom menu component and we need all the current props and state in the rendered Select component, hence the restructuring {...props} of props.
  • prop.children renders the children of the menu component. In this case, the options are rendered. Just after props.children is the button we want to position at the bottom of the menu.
  • selectProps is a property on the props object that exposes all props (custom and in-built) you passed to react-select. In this case, it exposes the custom changeOptionsData props (which we will soon pass a function as it’s value) we passed to the select element.
  • To add more custom functionality to our Select component, we wrote a conditional statement that will display either a span element with the fetching data… text for when we want to mimic a network request or a div element that display the menu’s children.

STEP 9: Add some styles to improve our button display.

button styles

STEP 10: pass the fetchingdata & the button onClick handler (changeOptionsData) as props from CustomSelect component to their respective references in app.js.

pass fetchingData & changeOptionsData as props.

STEP 11: For the onClick functionality, we want to display a different data set when we click our button. First, update our data.jsx with the second data set below.

Second, we import updatedCountries variable into app.jsx, and finally, we write our onClick handler (which is called changeOptionsData).

This is the code in app.js right now

adding onClick handler and updating state

Inside the handler function, we have the following logic.

  1. We set the fetchingData props to true (this will display the Fetching data… text)
  2. use a setTimeout function to mimic a network request.
  3. Inside the setTimeout, we update the data variable in state and set the fetchigData property in state to false.

STEP 12: Include styles for our label & fetching classes inside index.css

styles for fetching & label classes

Right now our Menu component is good to go. When we click the change data button, the fetching data… text pops up and after two seconds our data set is switched. If you’re still interested in more keeping reading to see how to create an Option component and use the selected value in the next steps.

STEP 13: Create a custom option component and pass it to the components prop. This is done pretty much the same way the menu component was created, rather we’re replacing the Menu property that is inside the component object (provided by react-select) with Option. Right now, our final react-custom.jsx looks like this

Final custom-select.jsx

I have decided not to do anything extra with the Option component. You can choose to add any functionality or styles you want to it.

STEP 14: Pass the onChange prop provided by react-select as a prop in CustomSelect component (I have already done so in the code snippet above) and pass the handleChange handler as a value to it in app.js.

onChange handler

The handleChange function grabs the selected option and set's it as a value for the selectedOption variable in the state.

STEP 15: Conditionally render the selected option inside a paragraph element that is placed above the Select element in app.js. Below is the final state of app.js.

And Voila!!! we’re done. Our custom react-select menu component is ready.

Customized react-select menu component

Go forth and customize any react-select component to your choice using the examples above.

You can fork the code from this codesandbox or Github repo. Also, drop your comments and questions in the comment box. I will reply to them as soon as I see them.

Resources

--

--

Juliet Onyekaoha

Frontend developer || Javascript Enthusiast || Avid Reader