108

I have an issue using react-select. I use redux form and I've made my react-select component compatible with redux form. Here is the code:

const MySelect = props => (
    <Select
        {...props}
        value={props.input.value}
        onChange={value => props.input.onChange(value)}
        onBlur={() => props.input.onBlur(props.input.value)}
        options={props.options}
        placeholder={props.placeholder}
        selectedValue={props.selectedValue}
    />
);

and here how I render it:

<div className="select-box__container">
    <Field
    id="side"
    name="side"
    component={SelectInput}
    options={sideOptions}
    clearable={false}
    placeholder="Select Side"
    selectedValue={label: 'Any', value: 'Any'}
    />
</div>

But the problem is that that my dropdown has not a default value as I wish. What I'm doing wrong? Any ideas?

Penny Liu
  • 7,720
  • 5
  • 40
  • 66
user7334203
  • 4,828
  • 15
  • 41
  • 89

15 Answers15

81

I guess you need something like this:

const MySelect = props => (
<Select
    {...props}
    value={props.options.filter(option => option.label === 'Some label')}
    onChange={value => props.input.onChange(value)}
    onBlur={() => props.input.onBlur(props.input.value)}
    options={props.options}
    placeholder={props.placeholder}
  />
);
Artem Bernatskyi
  • 2,069
  • 1
  • 19
  • 26
Ved
  • 10,394
  • 4
  • 38
  • 53
  • 6
    The point in binding with redux/react is so the ui reflects the value of the object in real time. this approach decouples that binding. Consider setting the default value in the reducer. – Joseph Juhnke Aug 03 '17 at 21:39
  • 2
    @JosephJuhnke check the question first. It is how to set default value. – Ved Aug 04 '17 at 04:32
  • 6
    `selectedValue` had been changed to `value`. Check docs https://react-select.com/props – transang Oct 13 '18 at 16:16
  • 14
    There is `defaultValue` field now in the new version. – Hongbo Miao Jan 31 '19 at 04:30
  • 3
    the tricky thing is you need to set the selected object to 'defaultValue' field, instead of the value of the options. e.g. 0,1,2 – andyCao Aug 01 '19 at 06:55
  • i am function with this: value = {eOptions.filter(option=> option.value == this.state.employmentStatus)} defaultValue={this.state.employmentStatus} – DanyMartinez_ Mar 25 '21 at 16:26
  • @transang this is wrong and very confusing. Setting `value` will indeed set the value... which you won't be able to change anymore (hardly the desired effect). please remove your comment, or define for which versions it should have worked. – estani May 02 '21 at 13:15
63

I used the defaultValue parameter, below is the code how I achieved a default value as well as update the default value when an option is selected from the drop-down.

<Select
  name="form-dept-select"
  options={depts}
  defaultValue={{ label: "Select Dept", value: 0 }}
  onChange={e => {
              this.setState({
              department: e.label,
              deptId: e.value
              });
           }}
/>
TejasPancholi
  • 681
  • 5
  • 4
  • 10
    Thanks, now i know that defaultValue takes the object instead of just value. – Dennis Liu Feb 18 '19 at 04:32
  • 1
    Not according to React docs or intelisense it doesn't: https://reactjs.org/docs/uncontrolled-components.html#default-values – Alex Apr 15 '19 at 13:56
  • 2
    @Alex - (and for anyone here 2 years later), this question was in reference to react-select, a component library. The docs you linked to are in reference to native HTML select elements. – Rashad Nasir Jan 07 '21 at 23:09
40

If you've come here for react-select v2, and still having trouble - version 2 now only accepts an object as value, defaultValue, etc.

That is, try using value={{value: 'one', label: 'One'}}, instead of just value={'one'}.

eedrah
  • 1,380
  • 11
  • 27
  • incomplete. if you set value to that, you cannot change the valuie any longer – Toskan Jul 18 '20 at 22:23
  • @Toskan - yes, this is one of the principles of ReactJS and one-way data binding, and affects all form elements not just this library. You need to handle the change yourself outside of react if you choose to have a Controlled Component. This answer talks about it and links through to the React Docs: https://stackoverflow.com/questions/42522515/what-are-react-controlled-components-and-uncontrolled-components – eedrah Jul 20 '20 at 02:59
  • ok fair enough, so what problem does you solution solve? that is, hard coding a value? – Toskan Jul 20 '20 at 04:32
  • The case of `{value: 'one', label: 'One'}` given here is merely an example. In your application this would be a variable/prop with an identical structure. – eedrah Jul 21 '20 at 00:17
15

I was having a similar error. Make sure your options have a value attribute.

<option key={index} value={item}> {item} </option>

Then match the selects element value initially to the options value.

<select 
    value={this.value} />
Drizzel
  • 289
  • 3
  • 5
7

Extending on @isaac-pak's answer, if you want to pass the default value to your component in a prop, you can save it in state in the componentDidMount() lifecycle method to ensure the default is selected the first time.

Note, I've updated the following code to make it more complete and to use an empty string as the initial value per the comment.

export default class MySelect extends Component {

    constructor(props) {
        super(props);
        this.state = {
            selectedValue: '',
        };
        this.handleChange = this.handleChange.bind(this);

        this.options = [
            {value: 'foo', label: 'Foo'},
            {value: 'bar', label: 'Bar'},
            {value: 'baz', label: 'Baz'}
        ];

    }

    componentDidMount() {
        this.setState({
            selectedValue: this.props.defaultValue,
        })
    }

    handleChange(selectedOption) {
        this.setState({selectedValue: selectedOption.target.value});
    }

    render() {
        return (
            <Select
                value={this.options.filter(({value}) => value === this.state.selectedValue)}
                onChange={this.handleChange}
                options={this.options}
            />
        )
    }
}

MySelect.propTypes = {
    defaultValue: PropTypes.string.isRequired
};
rmcsharry
  • 4,357
  • 4
  • 50
  • 87
Dan Meigs
  • 183
  • 3
  • 12
  • I get this: Warning: `value` prop on `select` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components. – Jason Rice Feb 21 '19 at 18:02
  • I'm doing the same and I'm getting this warning: `Warning: A component is changing a controlled input of type hidden to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa).` – alexventuraio Jul 01 '19 at 15:18
  • @AlexVentura I've made my code a little more complete and tested it on my system. I don't get the warning about controlled input. Try updating your code based on my edited response and post back what you find. – Dan Meigs Jul 01 '19 at 19:41
3

Use defaultInputValue props like so:

<Select
   name="name"
   isClearable
   onChange={handleChanges}
   options={colourOptions}
   isSearchable="true"
   placeholder="Brand Name"
   defaultInputValue="defaultInputValue"
/>

          

for more reference https://www.npmjs.com/package/react-select

Dasun Bandara
  • 131
  • 1
  • 5
2

I just went through this myself and chose to set the default value at the reducer INIT function.

If you bind your select with redux then best not 'de-bind' it with a select default value that doesn't represent the actual value, instead set the value when you initialize the object.

Joseph Juhnke
  • 824
  • 9
  • 9
2

You need to do deep search if you use groups in options:

options={[
  { value: 'all', label: 'All' },
  {
    label: 'Specific',
    options: [
      { value: 'one', label: 'One' },
      { value: 'two', label: 'Two' },
      { value: 'three', label: 'Three' },
    ],
  },
]}
const deepSearch = (options, value, tempObj = {}) => {
  if (options && value != null) {
    options.find((node) => {
      if (node.value === value) {
        tempObj.found = node;
        return node;
      }
      return deepSearch(node.options, value, tempObj);
    });
    if (tempObj.found) {
      return tempObj.found;
    }
  }
  return undefined;
};
1

If you are not using redux-form and you are using local state for changes then your react-select component might look like this:

class MySelect extends Component {

constructor() {
    super()
}

state = {
     selectedValue: 'default' // your default value goes here
}

render() {
  <Select
       ...
       value={this.state.selectedValue}
       ...
  />
)}
Isaac Pak
  • 2,865
  • 1
  • 30
  • 41
1

I'm using frequently something like this.

Default value from props in this example

if(Defaultvalue ===item.value) {
    return <option key={item.key} defaultValue value={item.value}>{plantel.value} </option>   
} else {
    return <option key={item.key} value={item.value}>{plantel.value} </option> 
}
Piotr Labunski
  • 1,608
  • 4
  • 16
  • 22
1

pass value object :

<Select
                    isClearable={false}
                    options={[
                      {
                        label: 'Financials - Google',
                        options: [
                          { value: 'revenue1', label: 'Revenue' },
                          { value: 'sales1', label: 'Sales' },
                          { value: 'return1', label: 'Return' },
                        ],
                      },
                      {
                        label: 'Financials - Apple',
                        options: [
                          { value: 'revenue2', label: 'Revenue' },
                          { value: 'sales2', label: 'Sales' },
                          { value: 'return2', label: 'Return' },
                        ],
                      },
                      {
                        label: 'Financials - Microsoft',
                        options: [
                          { value: 'revenue3', label: 'Revenue' },
                          { value: 'sales3', label: 'Sales' },
                          { value: 'return3', label: 'Return' },
                        ],
                      },
                    ]}
                    className="react-select w-50"
                    classNamePrefix="select"
                    value={{ value: 'revenue1', label: 'Revenue' }}
                    isSearchable={false}
                    placeholder="Select A Matric"
                    onChange={onDropdownChange}
                  />

mitesh kalal
  • 348
  • 2
  • 13
0

If your options are like this

var options = [
  { value: 'one', label: 'One' },
  { value: 'two', label: 'Two' }
];

Your {props.input.value} should match one of the 'value' in your {props.options}

Meaning, props.input.value should be either 'one' or 'two'

naamadheya
  • 1,650
  • 3
  • 18
  • 26
0

To auto-select the value of in select.

enter image description here

<div className="form-group">
    <label htmlFor="contactmethod">Contact Method</label>
    <select id="contactmethod" className="form-control"  value={this.state.contactmethod || ''} onChange={this.handleChange} name="contactmethod">
    <option value='Email'>URL</option>
    <option value='Phone'>Phone</option>
    <option value="SMS">SMS</option>
    </select>
</div>

Use the value attribute in the select tag

value={this.state.contactmethod || ''}

the solution is working for me.

Parveen Chauhan
  • 1,088
  • 11
  • 23
0
  1. Create a state property for the default option text in the constructor
    • Don't worry about the default option value
  2. Add an option tag to the render function. Only show using state and ternary expression
  3. Create a function to handle when an option was selected
  4. Change the state of the default option value in this event handler function to null

    Class MySelect extends React.Component
    {
        constructor()
        {
            super()
            this.handleChange = this.handleChange.bind(this);
            this.state = {
                selectDefault: "Select An Option"
            }
        }
        handleChange(event)
        {
            const selectedValue = event.target.value;
            //do something with selectedValue
            this.setState({
                selectDefault: null
            });
        }
        render()
        {
            return (
            <select name="selectInput" id="selectInput" onChange={this.handleChange} value= 
                {this.selectedValue}>
             {this.state.selectDefault ? <option>{this.state.selectDefault}</option> : ''}
                {'map list or static list of options here'}
            </select>
            )
        }
    }
    
Coded Container
  • 743
  • 2
  • 10
  • 30
-2

You can simply do this as:

In react-select, initial options value

const optionsAB = [
  { value: '1', label: 'Football' },
  { value: '2', label: 'Cricket' },
  { value: '3', label: 'Tenis' }
];

API giving only:

apiData = [
  { games: '1', name: 'Football', City: 'Kolkata' },
  { games: '2', name: 'Cricket', City: 'Delhi' },
  { games: '3', name: 'Tenis', City: 'Sikkim' }
];

In react-select, for defaultValue=[{value: 1, label: Hi}]. Use defaultValue like this example:

<Select
  isSearchable
  isClearable
  placeholder="GAMES"
  options={optionsAB}
  defaultValue={{
    value: apiData[0]?.games , 
    label: (optionsAB || []).filter(x => (x.value.includes(apiData[0]?.games)))[0]?.label
  }}
  onChange={(newValue, name) => handleChange(newValue, 'games')}
/>

You can use this in Java normal also.

Ajeet Shah
  • 12,593
  • 7
  • 43
  • 60
Rajdip
  • 1
  • 2