skip to Main Content

I am having an issue where, if I load my page for the first time things work perfectly fine. However when I try to navigate to another page, my api data is just completely lost.

Here is my tree:

App – Homepage
Pokemon – PokemonCard <— Here is where I think my issue is. The data is passed as a prop from the Pokemon component to the PokemonCard component

So for additional context, I am making an API call in a page, then passing that api data to the rendered child component. However the data seems to be lost in the process.

Here is the code for my pokemon page. Please let me know if youd like to see other code snippets.

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import PokemonCard from "./PokemonCard";
import axios from 'axios'

function PokemonPage() {

    const [pokemon, setPokemon] = useState();
    const { currentPokemon } = useParams();

    useEffect(() => {
        console.log("PokemonPage Mounted")
    }, [])

    useEffect(() => {
      const getPokeDetails = async () => {
          const response = await axios.get(
            `https://pokeapi.co/api/v2/pokemon/${currentPokemon}`
          );
          console.log(`API Data for ${currentPokemon} Loaded`)
          setPokemon(response.data);
        // const firstFourMoves = results.moves.slice(0,4).map(move => move.move.name);
        // setMoves(firstFourMoves)
      };

      getPokeDetails();
    }, [currentPokemon]);


    return (
    <>
        <h2>{currentPokemon}</h2>
        <PokemonCard pokemon={pokemon}/>
    </>
    )
}
export default PokemonPage;

2

Answers


  1. If you need to manage state across components I would urge you to use context instead of passing props. You can set the state in a global variable and as long as you don’t refresh the page or dom your variable will remain constant.

    If you are requiring data from an API storing context is the better method in my opinion. If you are storing a variable that doesn’t need to be fetched then localstoarge works as well.

    1. Create a new jsx file called PokemonContext.jsx
    import { createContext, useContext, useState } from "react";
    const UserContext = createContext();
    
    export default function PokemonContextProvider({ children }) {
      const [currentPokemon, setCurrentPokemon] = useState("pikachu");
    
      return (
        <UserContext.Provider
          value={{
            currentPokemon,
            setCurrentPokemon,
          }}
        >
          {children}
        </UserContext.Provider>
      );
    }
    
    export const PokemonValues = () => {
      return useContext(UserContext);
    };
    1. Wrap your App with the Context Provider
     <PokemonContextProvider>
        <App />
     </PokemonContextProvider>
    1. Now you can import the state into your variable
    import React, { useEffect, useState } from "react";
    import PokemonCard from "./PokemonCard";
    import axios from "axios";
    import { PokemonValues } from "../AuthContext";
    
    function PokemonPage() {
      const { currentPokemon } = PokemonValues();
    
      const [pokemon, setPokemon] = useState();
    
      useEffect(() => {
        console.log("PokemonPage Mounted");
      }, []);
    
      useEffect(() => {
        const getPokeDetails = async () => {
          const response = await axios.get(
            `https://pokeapi.co/api/v2/pokemon/${currentPokemon}`
          );
          console.log(`API Data for ${currentPokemon} Loaded`);
          setPokemon(response.data);
          // const firstFourMoves = results.moves.slice(0,4).map(move => move.move.name);
          // setMoves(firstFourMoves)
        };
    
        getPokeDetails();
      }, [currentPokemon]);
    
      return (
        <>
          <h2>{currentPokemon}</h2>
          <PokemonCard pokemon={pokemon} />
        </>
      );
    }
    export default PokemonPage;
    1. Now set your currentpokemon instead of running it as a paramater.
    Login or Signup to reply.
    • First of all, I recommand to setup the pokemon state to null at first,

      **const [pokemon, setPokemon] = useState(null);**
      
    • and check if the data is fetched before sending it to the Other Component :

      {pokemon ? < PokemonCard pokemon={pokemon} /> :

      Loading…

      }

    • if you can provide the Pockemoncard component and the main.js component will be great.

      console.log("Goodbye, Hope you find the solution asap!");

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search