I am querying the Pokeapi with React through axios. The request is made but, I can't display the data on the screen because my pokemons[] property is empty, that is, the request is made first and then the component is mounted and that is where the property is still empty.
I have tried to do it through hooks, with useState and then setting the pokemones property in the useEffect, and in the same useEffect is where I make the request to the api, I show it on the screen and if it arrives with data.
Here is my App.js
import React, { useState, useEffect } from "react";
import axios from "axios";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import { Button, Accordion, Card } from "react-bootstrap";
import "./style.css";
import HolaComponent from "./HolaComponent";
import AdiosComponent from "./AdiosComponent";
import Saludar from "./SaludarComponent";
import Contacto from "./pages/Contacto";
import About from "./pages/About";
import ListPokemon from "./pages/ListPokemon";
export default function App() {
let pokes = [];
const [pokemons, setPokemones] = useState([]);
useEffect(() => {
pokemonsListado().then(data => {
setPokemones(JSON.stringify(data.results));
console.log(`data ${JSON.stringify(data.results)}`);
});
console.log(pokemons);
}, []);
let url = `https://pokeapi.co/api/v2/pokemon?limit=10`;
// const pokemonsListado = async () => {
async function pokemonsListado() {
await axios.get(url).then(res => {
pokes = JSON.stringify(res.data.results);
console.log(`response: ${JSON.stringify(res.data.results)}`);
// return JSON.stringify(res.data.results);
});
}
return (
<>
<Router>
<Link to="/">
<Button>Home</Button>
</Link>
<Link to="/about">
<Button>About</Button>
</Link>
<Link to="/contacto">
<Button>Contacto</Button>
</Link>
<Link to="/pokemons">
<Button>Pokemons</Button>
</Link>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/contacto">
<Contacto />
</Route>
<Route path="/pokemons">
<ListPokemon />
</Route>
</Switch>
</Router>
<Saludar />
</>
);
}
And here my Pokemon component:
import React, { useState, useEffect } from "react";
import axios from "axios";
export default function ListPokemon() {
let url = `https://pokeapi.co/api/v2/pokemon?limit=10`;
// let pokemons = props.pokemons;
const [pokemons, setPokemones] = useState([]);
useEffect(() => {
pokemonsListado().then(data => {
setPokemones(JSON.stringify(data.results));
console.log(`data ${JSON.stringify(data.results)}`);
});
console.log(pokemons);
}, []);
// const pokemonsListado = async () => {
async function pokemonsListado() {
await axios.get(url).then(res => {
pokes = JSON.stringify(res.data.results);
console.log(`response: ${JSON.stringify(res.data.results)}`);
// return JSON.stringify(res.data.results);
});
}
console.log("los " + pokemons);
return (
<>
<ul>
{pokemons.map(p => (
<li>{p.name}</li>
))}
</ul>
</>
);
}
What I want to do is something like in Angular that has its OnInit and you can initialize data at the time the component loads.
I am working on this example on the StackBlitz platform, so that the problem is better understood, I leave the resource link:
Let's go by parts:
The life cycle
OnInit
inAngular
, can have its counterpart inReact
a method calledcomponentDidMount
, which will only be executed once and you can simulatehooks
it as you currently have it:Now let's try to understand that you are doing practically the same thing both in the component
App
and inListPokemon
(which is wrong) and this depends on who you want to delegate the responsibility of making the request, obtaining the information and putting it in the state.With the above clarified, I proceed to help you improve your component
App
in the following way, (I am going to simplify it and eliminate unnecessary code so that it is clear):And not being more, our child component could be simplified to avoid the redundancy of requests and information handling in the following way:
Here as a last resort I leave you a totally isolated example of what you want to do based on your snippet, functional and implemented as I just described in this whole answer: React-Axios-PokeAPI