0

The choice variables in useState do not always update. In the code below, I show the context file and my choices component. The context file holds the global state for my react app and the choices component is passed the setChoices method to update the state in GameContext. My setChoices method is supposed to update the value of each choice, but the state only updates randomly, not every time.

//GameContext file
import React, { createContext, useState } from 'react';

export const GameContext = createContext();

const GameContextProvider = props => {
    const [gameItems, setGameItems] = useState({
        user: {choice: null, score: 0},
        cpu: {choice: null, score: 0}
    })

    const setChoices = (userChoice, cpuChoice) => {
        setGameItems({
            ...gameItems, 
            user:{...gameItems.user, choice: userChoice},
            cpu: {...gameItems.cpu, choice: cpuChoice}
        });  
    }

    const cpuScore = () => {
      setGameItems({
         ...gameItems, 
         cpu:{...gameItems.cpu, score: gameItems.cpu.score + 1}
      })



 return (
        <GameContext.Provider value={{gameItems, setChoices}}>
            { props.children }
        </GameContext.Provider>
    )
}

//choices component
import React, { useContext } from 'react';
import { GameContext } from '../contexts/GameContext';

const Choices = (props) => {

    const {  setChoices } = useContext(GameContext);

    const getCpuChoice = () => {
        const cpuChoices = ['r', 'p', 's'];
        const randomIndex = Math.floor((Math.random() * 3));
        const cpuDecision = cpuChoices[randomIndex];
        return cpuDecision
    }

    const playGame = (e) => {
        const userChoice = e.target.id;
        const cpuChoice = getCpuChoice();

        setChoices(userChoice, cpuChoice);
        cpuScore();
    } 

    return (
            <div>
                <h1>Make Your Selection</h1>
                <div className="choices">
                    <i className="choice fas fa-hand-paper fa-10x" id="p" onClick={playGame}></i>
                    <i className="choice fas fa-hand-rock fa-10x" id="r" onClick={playGame}></i>
                    <i className="choice fas fa-hand-scissors fa-10x" id='s' onClick={playGame}></i>
                </div>
            </div>
        )
    }

I expect the choice property for user and cpu to update each time setChoices is called. Is there something wrong with the way I'm updating the state?

user2954945
  • 121
  • 9

2 Answers2

0

I did a little setup to try to emulate https://codesandbox.io/s/festive-almeida-4zx3c

What could cause the impression that is not always updating is that sometimes you will get the same values because of that randomIndex

If the value output is the same as the previous it will not update. It will think that the state did not change.

Solutions:

Do a force update: How can I force component to re-render with hooks in React?

Or add an internal value to the state, something that always changes, something like a hash.

Ion
  • 1,262
  • 12
  • 19
0

Read: https://www.freecodecamp.org/news/get-pro-with-react-setstate-in-10-minutes-d38251d1c781/

Shallow comparison of object causes this kind of behavior.

Ian
  • 544
  • 3
  • 16