Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 747
Mingu Avatar asked Jul 05 '16 03:07

Mingu


People also ask

How do I get the selected option value in React select?

To fetch the selected value from the select element, you can use the onChange event handler prop. Just like the input or textarea elements, you can use the onChange event handler to get the value from the event object. Now, make this select input element controlled by using the state to pass the value.

How do I create a dynamic drop down list in React?

Create two state variables countries and colours to store the details of few countries and colours as an array and an object respectively. Inside the constructor() , initialize the countries state variable to an empty array [] and the colours variable to an empty object {} .


2 Answers

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>
  );
};
like image 99
LasaleFamine Avatar answered Oct 16 '22 08:10

LasaleFamine


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

<select value={selectedOptionId}>
  {option_id.map(id =>
    <option key={id} value={id}>{options[id].name}</option>
  )}
</select>
like image 34
hellojebus Avatar answered Oct 16 '22 06:10

hellojebus