最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React defaultValue for Select with Dynamically Generated Options - Stack Overflow

programmeradmin6浏览0评论

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 ponentDidUpdate() and onChange event.

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

Thanks.

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 ponentDidUpdate() and onChange event.

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

Thanks.

Share Improve this question asked Jul 5, 2016 at 3:10 MinguMingu 1211 gold badge1 silver badge6 bronze badges 1
  • Any input on how you resolved this? – Charles Watson Commented Jun 1, 2018 at 6:50
Add a ment  | 

5 Answers 5

Reset to default 6

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 ponents 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, e.g.:

<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 ponent 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 best solution that I could find is to set key attribute the same as defaultValue so it will be a different element.

Aftermaths are not researched by me but I believe it should be okay.

You can do something like this, React will plain because it uses value instead of selected for consistency across the form ponents, more information.

const {useState} = React;

const Example = ({title}) => {
    const [states, setStates] = useState({
      selected: "Florida",
      values: [{name: "Alabama", code: "AL"}, {name: "Hawai", code: "HW"},{name: "Florida", code: "FL"}]
     });
  
    return (
       <select
      className="w-full"
      onChange={(e: any) => {
        setStates({
          ...states,
          selected: e.target.value,
        });
      }}
    >
      {states.values.map((state) => (
        <option
          value={state.name}
          key={state.name}
          selected={state.name === states.selected}
        >
          {state.name}
        </option>
      ))}
    </select>
    );
};


ReactDOM.createRoot(
    document.getElementById("root")
).render(
    <Example title="Example using Hooks:" />
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare./ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

发布评论

评论列表(0)

  1. 暂无评论