111

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?

Hitmands
  • 13,491
  • 4
  • 34
  • 69
Marc
  • 2,900
  • 3
  • 26
  • 40
  • 1
    You can use the value null – user3808307 Jul 05 '20 at 22:12
  • 4
    I tried and wasted my time using react-select. the simplicity of resetting the form is missing then why one should use this? it is made to much complicated and the tutorial is also something only the maker can understand. – Amit Shah Apr 23 '21 at 09:06
  • yep. Rather than set it up with Ref which didn't work, the simplest solution which ended up working was just setting the value to null. – Yarden Hochman Jun 21 '21 at 12:53

25 Answers25

79

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 || ''}
  ...
/>
TPHughes
  • 1,437
  • 11
  • 13
  • 3
    Really good one. In case your selected value is object, use ``my_unique_select_key__${JSON.stringify(selected)}``. – Sandy Sep 21 '19 at 20:46
  • 1
    This works but note that it cases the input to lose focus. You can [refocus it imperatively](https://react-select.com/advanced#methods) if that matters. – Tamlyn Dec 13 '19 at 11:30
  • 2
    Just `value={selected || ''}` solved it for me – Daya Jan 22 '21 at 12:17
  • 1
    can someone explain here what is `selected`? a variable or keyword or just string? – Amit Shah Apr 23 '21 at 08:44
  • 1
    `selected` is stored in state somewhere whilst you are tracking the current state of the dropdown. This should be updated when the user makes a new selection. This will cause the key to change and will re-render the component, so passing it the currently selected value will ensure that it does so with the correct selection, – TPHughes Apr 23 '21 at 11:41
  • if value is an object `value={this.state.selected && Object.keys(this.state.selected).length ? this.state.selected : null}` – Tristanisginger May 19 '22 at 12:03
  • This is the correct answer. It's annoying that this works but it will force a re-render which is the heart of the issue. – Andrew Aug 25 '22 at 13:50
  • This is so good. One-liner!! – hungdoansy Nov 30 '22 at 04:27
  • Does anyone know what exactly `key` does that makes select component re-render? – TheUnKnown Jan 06 '23 at 18:48
  • 1
    @TheUnKnown The key is used to identify a component. When it changes, React thinks the component has changed and re-renders it. See documentation: https://reactjs.org/docs/lists-and-keys.html#keys – TPHughes Jan 13 '23 at 09:25
  • A bit hacky but a good solution. Thanks! – JBrown Apr 25 '23 at 18:41
  • Works even if the value was previous fulfilled! Thanks! – Douglas Morais Jul 26 '23 at 18:46
63

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.

Artur N
  • 738
  • 5
  • 6
  • 1
    Please provide a (simplified) code-example in your answer, since links aren't permanent. – klaasman May 18 '18 at 19:40
  • Hey, I am new to react-select, may i know what is this doing: `select: { value: options[0], options } – AKJ Jan 14 '19 at 10:31
  • @AKJ The part `value: options[0]` means that react-select will have the option `"One"` as initial value. (also added explanatory comment for this line) – Artur N Jan 15 '19 at 17:17
  • 3
    I will add that clearing the value only works with null. If you pass undefined (like I was), the selected value will remain.. – mihkov Jun 20 '19 at 17:42
  • 5
    nothing worked. react-select is hell.. too much complicated just to reset it. if we spend a day resetting a select control.. when should we submit it? – Amit Shah Apr 23 '21 at 09:07
  • This doesn't work because the select box does not re-render when value is changed programatically. – Andrew Aug 25 '22 at 13:49
  • working for me by passing the `null` value instead of an undefined or empty string – Sigit Jan 08 '23 at 12:34
30

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

ziishaned
  • 4,944
  • 3
  • 25
  • 32
  • It shows me an error: The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes>> & Readonly<...> & Readonly<...>' – Lalitesh Upadhyaya Dec 27 '20 at 12:21
  • Hi @Zeeshan Ahmad can you please let me know how can i clear the values using the refs and not add them back to the options list ??? – Phil Feb 17 '21 at 17:26
  • 3
    In case of `import CreatableSelect from 'react-select/creatable'`, you need to use `creatableSelectRef.current.select.select.clearValue()` – michal Mar 03 '21 at 10:33
  • 3
    just too reset a select box if we need to use ref then it's the end of a developer's life. – Amit Shah Apr 23 '21 at 09:10
  • Thanks, you save my day. This way is the only way I find fit with my project, even just using `useRef` to only clear the select box. – Viet Nguyen Jan 28 '22 at 04:13
  • 3
    @LaliteshUpadhyaya if you want to deal with typescript with this solution you should use the useRef() generic version. That way you can get rid of the annoying ts error. Although I would preferably use selectInputRef.current.setValue("") to clear the select value in react-select version 5+. – Pepe Alvarez Feb 03 '22 at 02:51
  • 1
    selectInputRef.current.clearValue(); worked for me. – Niju Jun 04 '22 at 23:01
  • I have used the above example, getting following error. Uncaught TypeError: Cannot read properties of undefined (reading 'clearValue') – Rag ch May 19 '23 at 08:00
17

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.

Mahipal Reddy
  • 389
  • 6
  • 20
9

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

<Select value={null} />
Bogdan
  • 372
  • 3
  • 3
6

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>
);
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
5

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}
           /> 
}
Kira
  • 171
  • 1
  • 4
  • 11
5

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

Vincent Peres
  • 1,003
  • 1
  • 13
  • 28
4

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

Lint
  • 895
  • 3
  • 13
  • 32
3

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")
    }

GavinBelson
  • 2,514
  • 25
  • 36
Vladislav Sorokin
  • 369
  • 1
  • 2
  • 14
3

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;
Dharman
  • 30,962
  • 25
  • 85
  • 135
Abhishek Gangwar
  • 2,168
  • 18
  • 26
2

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
Pixelomo
  • 6,373
  • 4
  • 47
  • 57
2

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>
ravthiru
  • 8,878
  • 2
  • 43
  • 52
2

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;

StasNemy
  • 142
  • 2
  • 4
mayor
  • 49
  • 5
2

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}
/>
Tristanisginger
  • 2,181
  • 4
  • 28
  • 41
1

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

Harminder Singh
  • 183
  • 1
  • 8
1

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>
    );
  }
}
Dante Nuñez
  • 439
  • 4
  • 7
0
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])
Pankaj
  • 169
  • 2
  • 11
0

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>
    </>
  )
}
serraosays
  • 7,163
  • 3
  • 35
  • 60
0

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

0

This bugged me so here it is:

React select uses arrays so you have to pass an empty array not null.

Using React's useState:

import ReactSelect from 'react-select'

const Example = () => {

     const [val, setVal] = useState()

     const reset = () => {
         setVal([])
     }

     return <ReactSelect  
         value={val}/>
}

export default Example
0
  1. Create a function called onClear, and setSelected to empty string.
  2. Inside the handle submit function, call the onClear function.

This will work perfectly.

Example code:

const onClear = () => {
  setSelected("");
};
    
const handleSubmit = ()=>{
 1 your data first ......(what you are posting or updating)
 2 onClear();
}
fatihyildizhan
  • 8,614
  • 7
  • 64
  • 88
0

To clear value of react-select programmatically:

let ref = useRef(null);

input field:

<Select ref={selectInputRef} ...other options/>

reset function / method:

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

most of users have shared the code with selectInputRef.current.select.clearValue() but this one is for older version of react-select

Abdullah R.
  • 11
  • 1
  • 2
-1
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])
Pankaj
  • 169
  • 2
  • 11
-3

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

IlGala
  • 3,331
  • 4
  • 35
  • 49