ReactJs 18.2 useState not updating component consistently [duplicate]

I have a component that generates a series of elements based on an array called game_letters, whose length is determined by another array, letter_of_rec that contains a varying number of letters. When a user enters a letter, a function compares the entered letter to the same index in letter_of_rec to see if there is a match, and if there is then that value is entered in the same position in game_letters.

I have another function, AdLetter, that, if the user clicks a button, enters a random letter in game_letters. The issue is that when the state is updated in the AdLetter function, the letters appear in the inputs whereas when a user enters a letter, including those entered by the user.

When the user enters a letter, though the state is set as in AdLetter, no letters appear.

import React, { useState, useEffect }  from 'react';



const Word: React.FC = () => {

  const [game_letters, setGameLetters] = useState<GameLetter[]>([]);



  useEffect(() => {
    getGameLetterArray(letter_of_rec.length);
  }, [letter_of_rec]);

 
  const getGameLetterArray=(length:number)=>{
    const workArray:GameLetter[] = [];
    for(let i=0; i<length;i++) {
      let key:number = genRandNum(1000);
         workArray.push({key:key, val:"", needsTrans:false});
     }
   
     setGameLetters(workArray);
    
  }

  function adLetter(){  
     let indexArray = rtnIdxArray(game_letters);
     console.log("array of available indexes is ");
     console.log(indexArray);
     let len = indexArray.length;
    let rand = genRandNum(len);
    let letterToAdd = letter_of_rec[rand];
    const workArray:GameLetter[] = rtnArrayWithVal(game_letters,rand,letter_of_rec[rand]);
    setGameLetters(workArray);
   // console.log(letter_of_rec);
   }


  const onHandleAttempt = (index: number, event: React.ChangeEvent<HTMLInputElement>) => {
    if (/[a-zA-Z]/.test(event.target.value))
    {
       let attempt = event.target.value;
        letter_of_rec.forEach((val,idx)=>{    
      if(letter_of_rec[idx]===attempt){
          
           updateGameLetter(attempt,idx);  
           console.log("game letters");
           console.log(game_letters)
               
        }
     });
    }
     
  };

   
  const updateGameLetter = (val:string, index:number)=>{
    //console.log("update Game letter index "+val);
    //console.log("update Game letter index "+index)
    if(letter_of_rec[index]===val){    
       const workArray:GameLetter[] = game_letters;
       console.log("workarray");
       console.log(workArray);
       workArray[index].val=val;
       setGameLetters(workArray);
       console.log("game letters after update");
       console.log(game_letters);
    }
    

    //console.log("work array is "+workArray);
   
  };  


  

  
  return (
    <div className="wordWrapper">
        <p>{word}</p>
        <p>{word.length}</p>
      <div className="letter_box">
  

 
             
  {game_letters.length > 0 && // Add a conditional check here
          game_letters.map((letter, idx) => {
            return (
              <input
                key={letter.key}
                value={letter.val}
                onChange={(e) => onHandleAttempt(idx, e)}
              />
            );
          })
    }
              <Hint truWordId={wordId} hintList={hints}></Hint>
            
        
      </div>
       
      <div className="gameButtonBox">
          <button onClick={adLetter}>Add Letter</button>
         <button onClick={newGame} >New Game</button>
         <button onClick={removeHint} >Need hint</button>
        
      </div>
    </div>
   
  ); 
};

export default Word;

  • Where is letter_of_rec defined? prop, state?

    – 

Maybe the issue is with this line: const workArray:GameLetter[] = game_letters;. Try making a deep copy of game_letters, like this const workArray:GameLetter[] = [...game_letters];

Leave a Comment