The props on the ‘GameState’ component do not update correctly after changing their state from, they are always one iteration behind what the actual value of the state is as shown in the GIF and the sate is always one iteration behind when I try console.logging it too
import GameInfo from './components/GameInfo'; import GameState from './components/GameState'; import InputField from './components/InputField'; import StartButton from './components/StartButton'; import TheWord from './components/TheWord'; import WordsBox from './components/WordsBox'; function App() { const [currentDifficulty, setCurrentDifficulty] = useState({ time: 7, wordCount: 15, }); const changeDifficultyHandler = (difficulty) => { setCurrentDifficulty(difficulty); }; return ( <div> <header> Type Master </header> <main> <GameInfo onChangeDifficulty={changeDifficultyHandler} /> <TheWord /> <InputField /> <StartButton /> <WordsBox /> <GameState difficulty={currentDifficulty} /> </main> </div> ); } export default App;
import React from 'react'; const GameState = (props) => { return ( <div> <div>Time Left: {props.difficulty.time} Seconds</div> <div>Score: 0 From {props.difficulty.wordCount}</div> </div> ); }; export default GameState;
expected values:
const levels = { Easy: { time: 7, wordCount: 15, }, Normal: { time: 5, wordCount: 25, }, Hard: { time: 3, wordCount: 30, }, };
Code at the GameInfo component:
import { useState } from 'react'; const GameInfo = (props) => { const levels = { Easy: { time: 7, wordCount: 15, }, Normal: { time: 5, wordCount: 25, }, Hard: { time: 3, wordCount: 30, }, }; const [difficulty, setDifficulty] = useState(levels.Easy); const changeDifficultyHandler = (event) => { setDifficulty(levels[event.target.value]); props.onChangeDifficulty(difficulty); }; return ( <div> You Are Playing On The{' '} <span> [ <select onChange={changeDifficultyHandler}> <option value='Easy'>Easy</option> <option value='Normal'>Normal</option> <option value='Hard'>Hard</option> </select> ] </span>{' '} Difficulity & You Have{' '} <span className='text-main font-poppins font-bold'> [ {difficulty.time} ] </span>{' '} Seconds To Type The Word. </div> ); }; export default GameInfo;
Advertisement
Answer
Set state is async, so in changeDifficultyHandler
, difficulty
is still referencing the old value because it hasn’t updated yet. A simple fix would be changing props.onChangeDifficulty(difficulty)
to props.onChangeDifficulty(levels[event.target.value])
.
That said, storing the same state in two places isn’t best practice. Why not just keep the state in App
and pass it to GameInfo
as a prop like <GameInfo onChangeDifficulty={changeDifficultyHandler} difficulty={currentDifficulty} />
?