Piyush
Piyush

Reputation: 3285

Warning: Use the 'defaultValue' or 'value' props on <select> instead of setting 'selected' on <option>

SCENARIO A user has a dropdown and he selects an option. I want to display that dropdown and make that option a default value which was selected by that user last time.

I am using selected attribute on option but React generates a warning asking me to use default value on select.

For e.g.

render: function() {
    let option_id = [0, 1];
    let options = [{name: 'a'}, {name: 'b'}];
    let selectedOptionId = 0

    return (
      <select defaultValue={selectedOptionId}>
        {option_id.map(id =>
        <option key={id} value={id}>{options[id].name}</option>
        )}
      </select>
    )
  }
});

Problem is that I don't know the selectedOptionId as the selected option could be any option. How would I find the defaultValue ?

Upvotes: 169

Views: 308373

Answers (10)

Mugikuyu
Mugikuyu

Reputation: 1

use defaultValue as suggested above <select

          <option>Please select</option>
          {categories.length > 0 &&
            categories.map((c) => (
              <option
                key={c._id}
                defaultValue={c._id}
                selected={c._id === parent}>
                {c.name}
              </option>
            ))}
        </select>

Upvotes: 0

From options, you should be instead of value to defaultValue from options of that select:->

<select className="form-control text-align:center" onChange={handleChangeCountry}>
            <option type="others" >Select a Country</option>
            {users?.length > 0 && users.map(item => {
              return (<option selected={item.country_name === countryName} key={item.country_id} defaultValue={item.country_id} >
                {item.country_name}
              </option>)
            })}
          </select>

Upvotes: 0

Vasil Shterev
Vasil Shterev

Reputation: 9

I tried different options to avoid console errors the following option worked with selected option without errors in console:

    {const [myValue, setMyValue] = useState('');  
  const changeHandler = (e) => {
    setMyValue(e.target.value);
  };
<select id="select" value={myValue} onChange={changeHandler}>
            {!myValue&& <option value="">choise from list</option>}
            {elementsArr.map((el) => {
              return (
                <option key={el.id} value={el.name}>
                  {el.name}</option>
              );
            })
          </select>}

Upvotes: 0

Sandeep Amarnath
Sandeep Amarnath

Reputation: 6926

Use defaultValue and onChange like this

const [myValue, setMyValue] = useState('');

<select onChange={(e) => setMyValue(e.target.value)} defaultValue={props.myprop}>
                    
       <option>Option 1</option>
       <option>Option 2</option>
       <option>Option 3</option>

</select>

Example https://codesandbox.io/s/priceless-lamarr-fetpr?file=/src/App.js

Upvotes: 7

rsb
rsb

Reputation: 383

A simple solution to set the value without using selected in option,

follow these steps:

Default the value to 0 [which I am not considering it as a value to be in use] to x-column

Refer the imageenter image description here

4 steps

  1. set the "IntialValue" of the x-column : 0 to the
  2. use the same string used in your [selected] and set it here with the if condition and when found, mark the "values.x-column = 0"
  3. Remove the "selected" and other items set [if any] in tag 4.finally set this condition

now navigate , the value in the column is defaulted to the one which is marked in step-2 / that you wanted to be set in selected

I have tried and its working for me

A small correction.. line 45 in image.. read the column as column_value_id

Upvotes: 1

Joomler
Joomler

Reputation: 2808

With Hooks and useState

Use defaultValue to select the default value.

    const statusOptions = [
        { value: 1, label: 'Publish' },
        { value: 0, label: 'Unpublish' }
    ];
    const [statusValue, setStatusValue] = useState('');
    const handleStatusChange = e => {
        setStatusValue(e.value);
    }

return(
<>
<Select options={statusOptions} 
    defaultValue={[{ value: published, label: published == 1 ? 'Publish' : 'Unpublish' }]} 
    onChange={handleStatusChange} 
    value={statusOptions.find(obj => obj.value === statusValue)} required />
</>
)

Upvotes: 2

robertwerner_sf
robertwerner_sf

Reputation: 1313

Thank you all for this thread! My colleague and I just discovered that the default_value property is a Constant, not a Variable.

In other React forms I've built, the default value for a Select was preset in an associated Context. So the first time the Select was rendered, default_value was set to the correct value.

But in my latest React form (a small modal), I'm passing the values for the form as props and then using a useEffect to populate the associated Context. So the FIRST time the Select is rendered, default_value is set to null. Then when the Context is populated and the Select is supposed to be re-rendered, default_value cannot be changed and thus the initial default value is not set.

The solution was ultimately simple: Use the value property instead. But figuring out why default_value didn't work like it did with my other forms took some time.

I'm posting this to help others in the community.

Upvotes: 7

0DDC0
0DDC0

Reputation: 5189

In an instance where you want to set a placeholder and not have a default value be selected, you can use this option.

      <select defaultValue={'DEFAULT'} >
        <option value="DEFAULT" disabled>Choose a salutation ...</option>
        <option value="1">Mr</option>
        <option value="2">Mrs</option>
        <option value="3">Ms</option>
        <option value="4">Miss</option>
        <option value="5">Dr</option>
      </select>

Here the user is forced to pick an option!

EDIT

If this is a controlled component

In this case unfortunately you will have to use both defaultValue and value violating React a bit. This is because react by semantics does not allow setting a disabled value as active.

 function TheSelectComponent(props){
     let currentValue = props.curentValue || "DEFAULT";
     return(
      <select value={currentValue} defaultValue={'DEFAULT'} onChange={props.onChange}>
        <option value="DEFAULT" disabled>Choose a salutation ...</option>
        <option value="1">Mr</option>
        <option value="2">Mrs</option>
        <option value="3">Ms</option>
        <option value="4">Miss</option>
        <option value="5">Dr</option>
      </select>
    )
}

Upvotes: 144

Sammy I.
Sammy I.

Reputation: 2735

What you could do is have the selected attribute on the <select> tag be an attribute of this.state that you set in the constructor. That way, the initial value you set (the default) and when the dropdown changes you need to change your state.

constructor(){
  this.state = {
    selectedId: selectedOptionId
  }
}

dropdownChanged(e){
  this.setState({selectedId: e.target.value});
}

render(){
  return(
    <select value={this.selectedId} onChange={this.dropdownChanged.bind(this)}>
      {option_id.map(id =>
        <option key={id} value={id}>{options[id].name}</option>
      )}
    </select>
  );
}

Upvotes: 14

ryanjduffy
ryanjduffy

Reputation: 5215

React uses value instead of selected for consistency across the form components. You can use defaultValue to set an initial value. If you're controlling the value, you should set value as well. If not, do not set value and instead handle the onChange event to react to user action.

Note that value and defaultValue should match the value of the option.

Upvotes: 156

Related Questions