185

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
  • 15,447
  • 5
  • 79
  • 98
RamAlx
  • 6,976
  • 23
  • 58
  • 106

25 Answers25

148

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}
  />
);

#EDIT 1 : In the new version

const MySelect = props => (
<Select
    {...props}
     options={props.options} 
    onChange = {value => props.input.onChange(value)}
    onBlur={() => props.input.onBlur(props.input.value)}//If needed
    defaultValue={props.defaultValue || 'Select'}
    options={props.options}
    placeholder={props.placeholder}
  />
);
Ved
  • 11,837
  • 5
  • 42
  • 60
  • 8
    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
  • 3
    @JosephJuhnke check the question first. It is how to set default value. – Ved Aug 04 '17 at 04:32
  • 8
    `selectedValue` had been changed to `value`. Check docs https://react-select.com/props – Sang Oct 13 '18 at 16:16
  • 32
    There is `defaultValue` field now in the new version. – Hongbo Miao Jan 31 '19 at 04:30
  • 7
    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
  • `options={props.options}` is not required once you done `{...props}` – Qamar Feb 01 '22 at 12:30
118

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
  • 1,231
  • 1
  • 7
  • 4
  • 27
    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
  • 5
    @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
  • the trick in the value of defaultValue as is not simple val but takes object instead. Thanks – Miftah Classifieds Apr 06 '23 at 20:55
52

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
  • 2,245
  • 18
  • 32
  • 3
    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
  • One way data binding doesn't mean data once set from a prop cannot be changed within the child component if so wishes. Which is exactly what will happen if `defaultValue` is used instead of `value` – Amartya Mishra Jun 11 '21 at 08:10
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
  • 297
  • 3
  • 5
12

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
  • 5,363
  • 6
  • 65
  • 108
Dan Meigs
  • 363
  • 4
  • 13
  • 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
8

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
  • 179
  • 2
  • 5
5

As I followed all the answers above, it came to my mind, I should write this.

you have to set the prop value, not the DefaultValue. I spent hours by using this, read the documentation, they mentioned to use the DefaultValue, but it is not working. correct way would be,

options=[{label:'mylabel1',value:1},{label:'mylabel2',value:2}]
seleted_option={label:'mylabel1',value:1}

<Select
options={options}
value={selected_option}/>
Shamsul Arefin
  • 1,771
  • 1
  • 21
  • 21
4

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 K
  • 694
  • 1
  • 11
  • 24
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
  • 854
  • 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;
};
2

Use defaultValue instead of selected

If you want to hide the value from the menu, use hidden:

<option defaultValue hidden>
   {'--'}
</option>
{options.map(opt => (
    <option key={opt} value={opt.replaceAll(/[,'!?\s]/gi, '')}>
       {opt}
    </option>
))}
Anas Abu Farraj
  • 1,540
  • 4
  • 23
  • 31
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
  • 4,467
  • 3
  • 42
  • 48
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,638
  • 4
  • 19
  • 26
1

Use <select value={stateValue}>. Make sure that the value in stateValue is among the options given in the select field.

IronmanX46
  • 558
  • 7
  • 16
1

couple of points:

  1. defaultValue works for initial render, it will not be updated on sequential render passes. Make sure you are rendering your Select after you have defaultValue in hand.

  2. defaultValue should be defined in form of Object or Array of Objects like this: {value:'1', label:'Guest'}, most bulletproof way is to set it as item of options list: myOptionsList[selectedIndex]

bFunc
  • 1,370
  • 1
  • 12
  • 22
1

In useForm hook of React-hook-form provide defaultValues parameter

const {
    control,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
    defaultValues: {
      select: { label: "20", value: 20 },
    },
  });

react-select component

<Select
     optons={[
        { value: "20", label: "20" },
        { value: "30", label: "30" },
        { value: "25", label: "25" },
      ]}
/>

OR

provide defaultValue attribute to react-select component

<Select
   defaultValue={{ label: "20", value: 20 }
   optons={[
      { value: "20", label: "20" },
      { value: "30", label: "30" },
      { value: "25", label: "25" },
   ]}
/>
Muhammad Usman
  • 143
  • 1
  • 6
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,902
  • 5
  • 21
  • 28
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,396
  • 12
  • 25
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
  • 863
  • 2
  • 12
  • 33
0

Wanted to add my two cents to this, using Hooks,

You can subscribe to props in the DropDown

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

const DropDown = (props) => {
  const { options, isMulti, handleChange , defaultValue } = props;
  const [ defaultValueFromProps, setdefaultValueFromProps ] = useState(undefined)

  useEffect(() => {
    
    if (defaultValue) {
      setdefaultValueFromProps(defaultValue)
    }
  }, [props])
  
  const maybeRenderDefaultValue = () => {
    if (defaultValue) {
      return { label: defaultValueFromProps, value: defaultValueFromProps }
    } 
  }
  return (
    <div>
      <Select 
        width='200px'
        menuColor='red'
        isMulti={isMulti} 
        options={options} 
        value={maybeRenderDefaultValue()}
        clearIndicator
        onChange={(e) => handleChange(e)}
      />
    </div>
  )
}

export default DropDown;

and then in the parent component either pass the initial value or changed value from state

<DropDown options={GenreOptions} required={true} defaultValue={recipeGenre === undefined ? recipe.genre : recipeGenre} handleChange={handleGenreChange}/>

Then if it's a fresh form (no default value) you won't have to worry since the useEffect will ignore setting anything

Jack Collins
  • 339
  • 1
  • 2
  • 13
-1

2022 example with Redux react with useSelector

As of 2022 there is a defaultValue option in react-select. Please note that if you are using getOptionLabel, and getOptionValue, you need to make your default value match those option params you set....

for example


const responder = useSelector((state) => state.responder)



<Select
              name="keyword"
              required={true}
              className="mb-3"
              styles={customStyles}
              components={animatedComponents}
              closeMenuOnSelect={true}
              options={keywords}
              defaultValue={responder ? responder[0]?.responder?.keyword?.map((el) => { return {title: el.title, _id: el._id}}): ""}
              getOptionLabel={({title}) => title}
              getOptionValue={({_id}) => _id}
              onChange={(_id) => setUpload({...upload, keyword: _id})}
              isMulti
              placeholder="select Keywords"
              isSearchable={true}
              errors={errors}
              innerRef={register({
                required: "Add your Keyword"
              })}
            />


rather than setting your defaultValue with {label: "this", value: "that}

I needed to set mine with defaultValue({title:"this", _id: "that"})

KingJoeffrey
  • 303
  • 5
  • 16
-1
<Input 
  type='select' 
   name='defaultproperty'
   id='propertyselect'      
    >  
                         <option 
                          key={id} 
                          value={item.propertyId}
                          id = {item.propertyName}
                          defaultValue = {orgPropertyId} 
                          selected={item.propertyId === orgPropertyId}
                         >
                          {item.propertyName}
                           </option>  
                ) 
            </Input>

use selected will serve the purpose of default value text

Paul
  • 31
  • 5
-1

i think you can use selected prop at tag

         <select
            defaultValue={plan.name}
            className="select w-full max-w-xs text-gray-700 mt-4"
          >
            {plans.vps.map((i) => (
              <option
                selected={plan.name == i.name}
                key={i.name}
                className="p-2 border"
                value={i.name}
              >
                {i.name}
              </option>
            ))}
          </select>

Look at this selected={plan.name == i.name} also take notice about value update defaultValue={plan.name}

Ahmed Elsayed
  • 338
  • 2
  • 11
-2

In react-select if you want to define for the custom label, try this.

  <Select
    getOptionLabel={({ name }) => name}
  />
Slava Rozhnev
  • 9,510
  • 6
  • 23
  • 39
Behram Bazo
  • 230
  • 2
  • 6
-3

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
  • 18,551
  • 8
  • 57
  • 87
Rajdip
  • 1
  • 2