简体   繁体   中英

React defaultValue for Select with Dynamically Generated Options

Use the defaultValue or value props on instead of setting selected on .

<select defaultValue="react">
 <option value="react">React</option>
 <option value="angular">Angular</option>
</select>

defaultValue would work with the above select tag. However, it does not seem to work with options generated by loop.

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

Probably options not fully been set when defaultValue was declared?

I could do manual assigning in componentDidUpdate() and onChange event.

But my question is - Is there any cleaner(better) way to solve it?

Thanks.

This is old, but since answer #1 is related to a controlled Select and the question seems to be related to uncontrolled Select I think is worth to leave some lines for future readers:

The problem is that for uncontrolled components React needs to know what are the options before the first render , since from that moment the defaultValue won't override the current value of the Select . This means that if you render the Select before the options it won't know what to select.

You can solve the problem avoiding the render before the options are available:

const RenderConditionally = ({ options, selected }) => options.length > 0 ? (
  <select defaultValue={selected}>
   {options.map(item => (
     <option key={item.id} value={item.value}>{item.label}</option>
   ))}
  </select>
) : null;

Or without ternary if you desire:

const RenderConditionally = ({ options, selected }) => {
  if (options.length === 0) {
    return null;
  }

  return (
    <select defaultValue={selected}>
      {options.map(item => (
        <option key={item.id} value={item.value}>{item.label}</option>
      ))}
    </select>
  );
};

For users running into this issue, you can get the desired functionality by using the value prop, instead of defaultValue , eg:

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

Most probably you have something wrong with option_id and options arrays structure, or selectedOptionId variable. The way you build your select component is ok.

I've made a fiddle where this code works fine:

render: function() {
let option_id = [0, 1];
let options = [{name: 'a'}, {name: 'b'}];
let selectedOptionId = 1
return (
  <select defaultValue={selectedOptionId}>
    {option_id.map(id =>
    <option key={id} value={id}>{options[id].name}</option>
    )}
  </select>
)

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM