1

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:

enter image description here

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>
    }
    
  })();
1
  • Your loop stops because you're using a return statement inside it, push option elements in an array instead and then return it Commented Mar 12, 2020 at 20:24

1 Answer 1

0

<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.createRoot(document.querySelector("#app"))
  .render(<Dropdown options={pokemon} />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="app"></div>

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.