'How to stop multiple API fetches in React

I'm really new to React so please understand if my explanation is not enough(I'll do my best to explain)

So what I'm trying to do is fetch an api, store it in a state variable, and make a button(that will toggle the toggle function) and so on...

const [randomPokemon, setRandomPokemon] = React.useState([])
    const [specifics, setSpecifics] = React.useState({})
    const [pokemonIndex, setPokemonIndex] = React.useState(1)
    const [disableButton, setDisableButton] = React.useState(false)

    React.useEffect(function() {
        fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonIndex}/`).then(res => res.json()).then(data => setRandomPokemon(prevState => data))
    }, [pokemonIndex])

    
    function disableBtn() {
        setDisableButton(prevState => !prevState);
        setTimeout((setDisableButton), 500)
    }
    
    
    function getRandomIndex(lowerBound, upperBound) {
        return Math.floor(Math.random() * (upperBound - lowerBound + 1)) + lowerBound;
    };
    
    
    function toggle(e) {
        const randomIndex = getRandomIndex(1, 898);
        e.preventDefault();
        setPokemonIndex(randomIndex);
        const newPokemon = {
            pokemonName: randomPokemon.name,
            pokemonId: randomPokemon.id,
            pokemonType: randomPokemon.types.map(type => type.type.name),
            pokemonAbility: randomPokemon.abilities.map(ability => ability.ability.name),
            pokemonImage: randomPokemon.sprites.other[`official-artwork`].front_default
        };
        disableBtn();
        setSpecifics(newPokemon)
    }

However, when I console log "specifics" I get this in my console. console image

Question: Is there any way to stop making my program to fetch multiple times (because I think fetching the same data three times will lead to performance issues.

Thanks in advance!



Solution 1:[1]

each update state or change property run useEffect method again

 React.useEffect(function() {
    const fetchData=async ()=>{ fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonIndex}/`)
    .then(res => res.json()).then(data => setRandomPokemon(prevState => data))
  }
  if(randomPokemon?.length===0)
    fetchData();
}, [pokemonIndex])

Solution 2:[2]

You can use one extra pokemonIndex variable which stores the previous index and write one condition in useEffect whether you get a new index value then the previous one then only you have to make an API call.

const [pokemonIndex, setPokemonIndex] = React.useState(1)
const [pereviousPokemonIndex, setPrevPokemonIndex] = React.useState(0)

React.useEffect(function() {
        if(pokemonIndex !== pereviousPokemonIndex) {
      fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonIndex}/`).then(res => res.json()).then(data => setRandomPokemon(prevState => data))
      setPrevPokemonIndex(pokemonIndex)
      }
    }, [pokemonIndex])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Arash Ghazi
Solution 2 Akash Chavda