How to programmatically clear/reset React-Select?

ReactSelect V2 and V3 seems to have several props like clearValue, resetValue and setValue. Whatever I'm trying, I'm not able to clear the selections programmatically. resetValue seems not to be accessible from the outside.

selectRef.setValue([], 'clear')
// or
selectRef.clearValue()

This does not clear the current selection.

Do I miss something here or is it not fully implemented yet?

162584 次浏览

If you're using react-select you can try to pass null to value prop.

For example:

import React from "react";
import { render } from "react-dom";
import Select from "react-select";


class App extends React.Component {
constructor(props) {
super(props);


const options = [
{ value: "one", label: "One" },
{ value: "two", label: "Two" }
];


this.state = {
select: {
value: options[0], // "One" as initial value for react-select
options // all available options
}
};
}


setValue = value => {
this.setState(prevState => ({
select: {
...prevState.select,
value
}
}));
};


handleChange = value => {
this.setValue(value);
};


handleClick = () => {
this.setValue(null); // here we reset value
};


render() {
const { select } = this.state;


return (
<div>
<p>
<button type="button" onClick={this.handleClick}>
Reset value
</button>
</p>
<Select
name="form-field-name"
value={select.value}
onChange={this.handleChange}
options={select.options}
/>
</div>
);
}
}


render(<App />, document.getElementById("root"));

Here's a working example of this.

In case it helps anyone, this is my solution: I created a button to clear the selected value by setting state back to it's initial value.

<button onClick={() => this.clearFilters()} >Clear</button>


clearFilters(){
this.setState({ startTime: null })
}

Full code sample below:

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


const timeSlots = [
{ value: '8:00', label: '8:00' },
{ value: '9:00', label: '9:00' },
{ value: '10:00', label: '10:00' },
]


class Filter extends React.Component {


constructor(){
super();
this.state = {
startTime: null,
}
}
  

startTime = (selectedTime) => {
this.setState({ startTime: selectedTime });
}


clearFilters(){
this.setState({
startTime: null,
})
}


render(){
const { startTime } = this.state;
    

return(
<div>
<button onClick={() => this.clearFilters()} >Clear</button>
<Select
value={startTime}
onChange={this.startTime}
options={timeSlots}
placeholder='Start time'
/>
</div>
)
}


}


export default Filter

If you check Select component in React Developers panel you will see that it is wrapped by another – State Manager. So you ref is basically ref to State manager, but not to Select itself.

enter image description here

Luckily, StateManager has state) and a value object which you may set to whatever you want.

For example (this is from my project, resetGroup is onClick handler that I attach to some button in DOM):

<Select onChange={this.handleGroupSelect}
options={this.state.groupsName.map(group =>
({ label: group, value: group }) )}
instanceId="groupselect"
className='group-select-container'
classNamePrefix="select"
placeholder={this.context.t("Enter name")}
ref={c => (this.groupSelect = c)}
/>


resetGroup = (e) => {
e.preventDefault()
this.setState({
selectedGroupName: ""
})
this.groupSelect.state.value.value = ""
this.groupSelect.state.value.label = this.context.t("Enter name")
}


I came across this problem myself and managed to fix it by passing a key to the React-Select component, with the selected value appended to it. This will then force the ReactSelect to re-render itself when the selection is updated.

I hope this helps someone.

import ReactSelect from 'react-select';


...


<ReactSelect
key={`my_unique_select_key__${selected}`}
value={selected || ''}
...
/>

Just store the value in the state, and change the state programmatically using componentDidUpdate etc...

class Example extends Component {


constructor() {
super()
}


state = {
value: {label: 'Default value', key : '001'}
}


render() {
return(
<Select
...
value={this.state.value}
...
/>
)
)}

Note: 'value' should be an object.

A simple option would be to pass null to the value prop.

<Select value={null} />

This is my working implementation of a React-Select V3 cleared programmatically with Hooks.

You can play with it in the CodeSandbox DEMO. Any feedback is welcome.

const initialFormState = { mySelectKey: null };


const [myForm, setMyForm] = useState(initialFormState);


const updateForm = value => {
setMyForm({ ...myForm, mySelectKey: value });
};


const resetForm = () => {
setMyForm(initialFormState);
};


return (
<div className="App">
<form>


<Select name = "mySelect"
options = {options}
value = {options.filter(({ value }) => value === myForm.mySelectKey)}
getOptionLabel = {({ label }) => label}
getOptionValue = {({ value }) => value}
onChange = {({ value }) => updateForm(value)} />


<p>MyForm: {JSON.stringify(myForm)}</p>


<input type="button" value="Reset fields" onClick={resetForm} />


</form>
</div>
);

I use redux-observable.

Initial state:

firstSelectData: [],
secondSelectData:[],
secondSelectValue: null

I create an action for filling first select. on change of first select, I call an action to fill second one.

In success of fill first select I set (secondSelectData to [], secondSelectValue to null)

In success of fill second select I set (secondSelectValue to null) on change of second select, I call an action to update secondSelectValue with the new value selected

If someone looking for solution using Hooks. React-Select V3.05:

const initial_state = { my_field: "" }


const my_field_options = [
{ value: 1, label: "Daily" },
{ value: 2, label: "Weekly" },
{ value: 3, label: "Monthly" },
]


export default function Example(){
const [values, setValues] = useState(initial_state);


function handleSelectChange(newValue, actionMeta){
setValues({
...values,
[actionMeta.name]: newValue ? newValue.value : ""
})
}


return <Select
name={"my_field"}
inputId={"my_field"}
onChange={handleSelectChange}
options={my_field_options}
placeholder={values.my_field}
isClearable={true}
/>
}

For those who are working with function component, here's a basic demo of how you can reset the react select Based on some change/trigger/reduxValue.

import React, { useState, useEffect } from 'react';
import Select from 'react-select';


const customReactSelect = ({ options }) => {
const [selectedValue, setSelectedValue] = useState([]);




/**
* Based on Some conditions you can reset your value
*/
useEffect(() => {
setSelectedValue([])
}, [someReduxStateVariable]);


const handleChange = (selectedVal) => {
setSelectedValue(selectedVal);
};


return (
<Select value={selectedValue} onChange={handleChange} options={options} />
);
};


export default customReactSelect;

You can clear the value of react select using the ref.

import React, { useRef } from "react";
import Select from "react-select";


export default function App() {
const selectInputRef = useRef();


const onClear = () => {
selectInputRef.current.select.clearValue();
};


return (
<div className="App">
<h1>Select Gender</h1>
<Select
ref={selectInputRef}
options={[
{ value: "male", label: "Male" },
{ value: "female", label: "Female" }
]}
/>
<button onClick={onClear}>Clear Value</button>
</div>
);
}

Here is the CodeSandbox link

You can set the value to null

   const [selectedValue, setSelectedValue] = useState();
const [valueList, setValueList] = useState([]);
const [loadingValueList, setLoadingValueList] = useState(true);




useEffect(() => {
//on page load update valueList and Loading as false
setValueList(list);
loadingValueList(false)
}, []);


                                

const onClear = () => {
setSelectedValue(null);  // this will reset the selected value
};


<Select
className="basic-single"
classNamePrefix="select"
value={selectedValue}
isLoading={loadingValueList}
isClearable={true}
isSearchable={true}
name="selectValue"
options={valueList}
onChange={(selectedValue) =>
setSelectedValue(selectedValue)}
/>
<button onClick={onClear}>Clear Value</button>

react-select/creatable.

The question explicitly seeks a solution to react-select/creatable. Please find the below code, a simple answer and solution to the question. You may modify the code for your specific task.

import CreatableSelect from "react-select/creatable";


const TestAction = (props) => {
const { buttonLabelView, className } = props;
const selectInputRef = useRef();


function clearSelected() {
selectInputRef.current.select.select.clearValue();
}


const createOption = (label, dataId) => ({
label,
value: dataId,
});


const Options = ["C1", "C2", "C3", "C4"]?.map((post, id) => {
return createOption(post, id);
});


return (
<div>
<CreatableSelect
ref={selectInputRef}
name="dataN"
id="dataN"
className="selctInputs"
placeholder=" Select..."
isMulti
options={Options}
/>


<button onClick={(e) => clearSelected()}> Clear </button>
</div>
);
};


export default TestAction;


if you are using formik then use below code to reset react-select value.


useEffect(()=>{
formik.setFieldValue("stateName", [])
},[])


Where stateName is html field name.


if you want to change value according to another dropdown/select (countryName) then pass that field value in useEffect array like below


useEffect(()=>{
formik.setFieldValue("stateName", [])
},[formik.values.countryName])
if you are using formik then use below code to reset react-select value.


useEffect(()=>{
formik.setFieldValue("stateName", [])
},[])


Where stateName is html field name.


if you want to change value according to another dropdown/select (countryName) then pass that field value in useEffect array like below


useEffect(()=>{
formik.setFieldValue("stateName", [])
},[formik.values.countryName])

passing null in value attribute of the react-select will reset it.

Zeeshan's answer is indeed correct - you can use clearValue() but when you do so, the Select instance isn't reset to your defaultValue prop like you might be thinking it will be. clearValue() returns a general Select... label with no data in value.

You probably want to use selectOption() in your reset to explicitly tell react-select what value/label it should reset to. How I wired it up (using Next.js, styled-components and react-select):

import { useState, useRef } from 'react'
import styled from 'styled-components'
import Select from 'react-select'


// Basic button design for reset button
const UIButton = styled.button`
background-color: #fff;
border: none;
border-radius: 0;
color: inherit;
cursor: pointer;
font-weight: 700;
min-width: 250px;
padding: 17px 10px;
text-transform: uppercase;
transition: 0.2s ease-in-out;


&:hover {
background-color: lightgray;
}
`


// Using style object `react-select` library indicates as best practice
const selectStyles = {
control: (provided, state) => ({
...provided,
borderRadius: 0,
fontWeight: 700,
margin: '0 20px 10px 0',
padding: '10px',
textTransform: 'uppercase',
minWidth: '250px'
})
}


export default function Sample() {
// State for my data (assume `data` is valid)
const [ currentData, setCurrentData ] = useState(data.initial)


// Set refs for each select you have (one in this example)
const regionOption = useRef(null)


// Set region options, note how I have `data.initial` set here
// This is so that when my select resets, the data will reset as well
const regionSelectOptions = [
{ value: data.initial, label: 'Select a Region' },
{ value: data.regionOne, label: 'Region One' },
]


// Changes data by receiving event from select form
// We read the event's value and modify currentData accordingly
const handleSelectChange = (e) => {
setCurrentData(e.value)
}


// Reset, notice how you have to pass the selected Option you want to reset
// selectOption is smart enough to read the `value` key in regionSelectOptions
// All you have to do is pass in the array position that contains a value/label obj
// In my case this would return us to `Select a Region...` label with `data.initial` value
const resetData = () => {
regionOption.current.select.selectOption(regionSelectOptions[0])
setCurrentData(data.initial)
}


// notice how my `UIButton` for the reset is separate from my select menu
return(
<>
<h2>Select a region</h2>
<Select
aria-label="Region select menu"
defaultValue={ regionSelectOptions[0] }
onChange={ event => handleDataChange(event) }
options={ regionSelectOptions }
ref={ regionOption }
styles={ selectStyles }
/>
<UIButton
onClick={ resetData }
>
Reset
</UIButton>
</>
)
}

Along the top answer, please note that the value needs to be "null" and not "undefined" to clear properly.

Nether of the solution help me. This work for me:

import React, { Component, Fragment } from "react";


import Select from "react-select";
import { colourOptions } from "./docs/data";


export default class SingleSelect extends Component {
selectRef = null;


clearValue = () => {
this.selectRef.select.clearValue();
};


render() {
return (
<Fragment>
<Select
ref={ref => {
this.selectRef = ref;
}}
className="basic-single"
classNamePrefix="select"
defaultValue={colourOptions[0]}
name="color"
options={colourOptions}
/>
<button onClick={this.clearValue}>clear</button>
</Fragment>
);
}
}

in v5, you can actually pass the prop isClearable={true} to make it clearable, which easily resets the selected value

None of the top suggestions worked for me and they all seemed a bit over the top. Here's the important part of what worked for me

<Select
value={this.state.selected && Object.keys(this.state.selected).length ? this.state.selected : null},
onChange={this.handleSelectChange}
/>

StateManager is abolished now, at least after version 5.5.0.
Now if you use ref, you can just do it like this:

selectRef = null
<Select
...
ref={c => (selectRef=c)}
/>
clearValue = () => {
selectRef.clearValue();
};


Here this c would be the Select2 React Component