Akhil Bisht
Akhil Bisht

Reputation: 53

Component not re-rendering even after state changed

I have this component in react and even after the state has been changed react component is not re-rendering.

import { useState, useEffect } from "react";

const Game = (props) =\> {

    const [pokemonData, setPokemonData] = useState([]);
    
    const shufflePokemon = () => {
        console.log("pokemon is shuffling....")
        let temp = pokemonData;
        for (let i = temp.length - 1; i >= 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var t = temp[i];
            temp[i] = temp[j];
            temp[j] = t;
        }
        setPokemonData(temp);
        console.log(pokemonData);
    }
    
    useEffect(() => {
        setPokemonData(props.data);
    }, [props.data])
    
    return (
        <div>
            {console.log("rendering")}
            {
                pokemonData.length === 0 ? null :
                    pokemonData.map((curr) => {
                        return (
                            <div onClick={shufflePokemon} key={curr.id} >
                                <img src={curr.image} />
                                <p>{curr.name}</p>
                            </div>
                        )
                    })
            }
        </div>
    )

}

I known that state has been changed because when i console.log(pokemonData) it shows me new shuffled list of pokemon data. But component is not re rendering.

When i click on any div containing pokemon image i want them to shuffle as well but component is not re-rendering even though state is changed so they are not changining on change of state.

Upvotes: 1

Views: 61

Answers (2)

Kuncheria
Kuncheria

Reputation: 1950

Try let temp = [...pokemonData]; instead of let temp = pokemonData; in shufflePokemon function.

What's happening here is you are mutating the state directly and when you are trying to set the data calling setPokemonData you are giving the same reference as argument. React does not identify the state change, as previous state and current state points to the same reference.

When you destructure the array using ... , temp will be referring to a new array.

Upvotes: 1

mikenlanggio
mikenlanggio

Reputation: 1137

Because pokemonData is the same reference as init data. You have to clone pokemonData Try to change shufflePokemon like that:

const shufflePokemon = () => {
    console.log("pokemon is shuffling....")
    let temp = [...pokemonData];
    for (let i = temp.length - 1; i >= 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var t = temp[i];
        temp[i] = temp[j];
        temp[j] = t;
    }
    setPokemonData(temp);
}

Upvotes: 1

Related Questions