Home > OS >  set State when fetch response in useEffect is a array
set State when fetch response in useEffect is a array

Time:08-22

This is fetching from Pokemon API which response with an array that I want to pass useState variable initialized as empty array with setValue function.

React component is below:

import React, { useState, useEffect } from "react";

export default function Pokemones() {
  const [pokemons, setPokemons] = useState([]);

  useEffect(() => {
    async function fetchData() {
      // Call fetch
      const res = await fetch("https://pokeapi.co/api/v2/pokemon/");
      // Pull out the data
      const json = await res.json();
      // Save the data to array
      console.log(json.results);
 }

    fetchData();
  }, []);

  return (
    <ul>
      {pokemons.map((pokemon) => (
        <li>
          <p>Name = {pokemon.name}</p>
          <p>URL = {pokemon.name}</p>
        </li>
      ))}
    </ul>
  );
}

I tried directly set setPokemons(json.results); or by json.results.map, received same error. I did other tries but I got similar errors

      // atfet console.log and before fetchData function 

      let pok = [];
      json.results.map((p) => (pok = [...pok, p]));
      console.log(pok);
      setPokemons(pok);
    }

The error received on consola is:

Uncaught Error: Objects are not valid as a React child (found: object with keys 
{name, url}). If you meant to render a collection of children, use an array instead.

I guess that array is not passing to variable pokemons but I am able to see in console the array. what part is that I am missing. thanks

CodePudding user response:

I hope this helps.

import React, { useState, useEffect } from "react";
    
    export default function Pokemones() {
      const [pokemons, setPokemons] = useState([]);
    
      useEffect(() => {
        async function fetchData() {
          // Call fetch
          const res = await fetch("https://pokeapi.co/api/v2/pokemon/");
          // Pull out the data
          const json = await res.json();
          // Save the data to array
          console.log(json.results);
          setPokemons(json.results);
     }
    
        fetchData();
      }, []);
    
      return (
        <ul>
          {pokemons.map((pokemon, index) => {
           return <li key={index}>
              <p>Name = {pokemon.name}</p>
              <p>URL = {pokemon.name}</p>
            </li>
          })}
        </ul>
      );
    }

CodePudding user response:

minimum example

Here's a minimum working example you can run here and verify the results in your own browser.

function App() {
  const [pokemon, setPokemon] = React.useState([])
  
  React.useEffect(_ => {
    fetch("https://pokeapi.co/api/v2/pokemon/")
      .then(res => res.json())
      .then(res => setPokemon(res.results))
      .catch(console.error)
  }, [])
  
  return <ul>
    {pokemon.map(p =>
      <li key={p.name}>
        <a href={p.url}>{p.name}</a>
      </li>
    )}
  </ul>
}

ReactDOM.render(<App/>, document.querySelector("#app"))
ul { list-style-type: none; padding-left: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

going further

We can expand the app's functionality a bit by making the list item's clickable and show the selected Pokémon details -

  • Related