简体   繁体   中英

Populate select options from an array in React

I have this API call that returns types of Pokemon as in:

["Grass", "Poison", "Fire", "Flying", "Water", "Bug", "Normal", "Electric", "Ground", "Fighting", "Psychic", "Rock", "Ice", "Ghost", "Dragon"]

This is a result of a function that takes all Pokemon values and filters out duplicates and such. The same function is used to take these values and populate the select options:

  let pokemonSingleType = (() => {
    let types = pokemonData.reduce((acc, { type }) => (acc.push(...type), acc), [])
    types = new Set(types);
    types = [...types];
    console.log(types);
    return <option>
      {types}
    </option>
  })();

That gets rendered below:

 <select value={searchType} onChange={updateSearchByType.bind(this)} 
  className="formcontrol" id="typeSelect">
  {pokemonSingleType}
</select>

The issue is that I get the whole array as one Select option value. Please see image below:

The output is as below:

在此处输入图片说明

Also, when I do a for loop before, it stops at the first iteration:

let pokemonSingleType = (() => {
    let types = pokemonData.reduce((acc, { type }) => (acc.push(...type), acc), [])
    types = new Set(types);
    types = [...types];
    for(let i =0; i< types.length; i++){
      return <option>
      {types[i]}
    </option>
    }
    
  })();

<option> tags should be placed around each element, not all of them. map is the most direct way to accomplish this:

 const Dropdown = ({options}) => <select> {options.map((e, i) => <option key={i}>{e}</option>)} </select> ; const pokemon = ["Grass", "Poison", "Fire", "Flying", "Water", "Bug", "Normal", "Electric", "Ground", "Fighting", "Psychic", "Rock", "Ice", "Ghost", "Dragon"]; ReactDOM.render(<Dropdown options={pokemon} />, document.body);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

For the second example, return inside the loop will only return the first element. You could push the JSX elements onto an array and return that, but this still seems like a lot of indirection.

In both examples, using reduce to spread each element in an array onto an array accumulator is an antipattern; map does this best.

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