React Select is an amazing input control with multiselect, autocomplete, async and creatable support.
Here’s a typical use case in which we are using Redux to manage the app’s global state along with React Hooks to move away from having to write classes to create a new component
//Setting up all of the necessary imports
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux'
import Select from 'react-select';
import makeAnimated from 'react-select/animated'
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'
We can really break up the rest of the component into several distinct parts. I’ll break them into smaller chunks below, but keep in mind the entire component has been broken up into smaller chunks to allow for some clarity.
const AddInterestsToEmployeeForm = (props) => {
const dispatch = useDispatch()
useEffect( () => {
dispatch(fetchAllInterests())
}, [])
const interests = useSelector(state => state.interests.interests)
const options = []
interests.map( (interest) => (
options.push({ value: interest.name, label: interest.name })
))
Above we’re fetching all interest objects by using the useEffect hook to dispatch the action and update the Redux store upon every render. From there we’re using the useSelector hook in order to update the component’s local state with the interests that were put into the Redux store. Finally we define a blank array and then iterate over the local state in order to produce an array full of objects containing the value and label keys for our Select input.
const [selectedOptions, setSelectedOptions] = useState([])
const handleChange = options => {
setSelectedOptions(options)
};
const handleSubmit = (e) => {
e.preventDefault()
let ee_interests = selectedOptions.map( int => (int.value))
dispatch(addInterestsToEmployee(ee_interests))
}
const animatedComponents = makeAnimated()
Here we’re setting up the logic to deal with the user interacting with the Select input field. const [selectedOptions, setSelectedOptions] = useState([]) is essentially creating a new variable called selectedOptions, creating a function called setSelectedOptions to allow us to update the variable, and useState([]) will set the initial value of selectedOptions to a blank array.
return (
<Form onSubmit={handleSubmit}>
<Select
closeMenuOnSelect={false}
components={animatedComponents}
isMulti
value={selectedOptions}
options={options}
onChange={handleChange}
/>
<Button variant="primary" type="submit">Assign</Button>
</Form>
);
Last but not least the part that actually gets rendered to the DOM. We’ve hooked up the form’s onSubmit event to the handleSubmit function we created earlier so when the user clicks the “Assign” button the form knows what to do. The Select tag itself has a lot of different options, which are documented very well on the official github repository, but the two most important here are value and onChange. The select element is getting all of its initial options from the redux store and is keeping track of what options the user has selected by updating the component’s local state via the onChange function we defined.