Hello I am making an website that shows pokemons from "https://pokeapi.co/api/v2/pokemon"
and I am displaying them with .map(). every one of those has image title and link I want to make link to go to the /{pokemon.name} and display it there but I don’t want to create file for every pokemon I want to have one file for every of them and display things based on which pokemon’s link was clicked and I want every to have also diffrent url like: pikachu -> http://example.com/pikachu, bulbasaur -> http://example.com/bulbasaur but I want to have one file for every one of them.
App.jsx:
import React from "react";
import Pokemons from "./Pokemons";
import {
BrowserRouter,
createBrowserRouter,
RouterProvider,
} from "react-router-dom";
import Pokemon from "./Pokemon";
function App() {
const router = createBrowserRouter([
{
path: "/",
element: <Pokemons />,
},
{
path: "/pikachu",
element: <Pokemon />,
},
]);
return (
<div>
<BrowserRouter>
<Pokemons />
</BrowserRouter>
<RouterProvider router={router} />
</div>
);
}
export default App;
Pokemons.jsx:
import React, { useEffect, useState } from "react";
import "./App.css";
import { Link, RouterProvider, createBrowserRouter } from "react-router-dom";
import Pokemon from "./Pokemon.jsx";
function Pokemons() {
const [pokemonDetails, setPokemonDetails] = useState([]);
const [routerPath, setRouterPath] = useState(["o"]);
useEffect(() => {
async function fetchData() {
const response = await fetch(
"https://pokeapi.co/api/v2/pokemon?limit=20"
);
const data = await response.json();
setPokemonDetails(
await Promise.all(data.results.map((p) => fetchPokemonDetails(p.url)))
);
console.log(pokemonDetails);
}
fetchData();
}, []);
async function fetchPokemonDetails(url) {
const response = await fetch(url);
const data = await response.json();
return data;
}
return (
<div>
<h2>Pokemony</h2>
<div id="pokemony">
{pokemonDetails.map((element, index) => (
<div className="jedenBlok" key={index}>
<h2 id={"Napis " + element.name} className="pokemoN">
{element.name}
</h2>
<img
src={element.sprites.front_default}
alt={`Pokemon ${index + 1}`}
id={"Pokemon " + element.name}
className="pokemon"
/>
<Link to="/pikachu">link</Link>
</div>
))}
</div>
</div>
);
}
export default Pokemons;
Pokemon.jsx:
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
function Pokemon() {
const [pokemon, setPokemon] = useState([]);
useEffect(() => {
async function fetchData() {
const response = await fetch(
"https://pokeapi.co/api/v2/pokemon?limit=20"
);
const data = await response.json();
setPokemon(
await Promise.all(data.results.map((p) => fetchPokemonDetails(p.url)))
);
}
fetchData();
}, []);
async function fetchPokemonDetails(url) {
const response = await fetch(url);
const data = await response.json();
return data;
}
return (
<div>
<Link to="/">main</Link>
{pokemon.map((pokemon, index) => (
<div key={index}>
<h1>{pokemon.name}</h1>
</div>
))}
</div>
);
}
export default Pokemon;
2
Answers
Update the router to render
Pokemon
on a single route with a dynamic route path.Update
Pokemons
to pass the details in route state to thePokemon
page.Update
Pokemons
to read the route state.I would not gather all data ahead of time. You can manually form an image URL from the ID within the URL values that come back from the paged response.
The only time you should request the full data for a Pokémon should be when you are viewing that particular Pokémon. It is expensive to make n-number of calls back to the API to stitch it all together.
App.jsx
This is where the routing occurs. Your app contains a
<RouterProvider>
.components/PokemonList.jsx
This is the main "home" route that lists Pokémon via an
offset
andlimit
.If you wanted only the legendary birds, you could load the following URL:
components/PokemonListItem.jsx
This is the Pokémon tile component that gets rendered in the list (grid) on the "home" route.
component/PokemonDetails.jsx
This is a thorough detail page explaining the selected Pokémon.
api/PokemonService.js
This is the central business logic for fetching Pokémon information.
index.css
The basic styles for the Pokémon list.
package.json
You will need React Router V6 and PropTypes to run the code above.