简体   繁体   中英

Handler function doesn't have access to updated state variable

first time i post here so please let me know if i'm doing things incorrectly. This being said, the problem with the following code is that the handleKeyUp function only seem to have access to the initial version of correctLetters and wrongLetters arrays

const WORDS = ['application', 'programming', 'interface', 'wizard']
const selectedWord = WORDS[Math.floor(Math.random() * WORDS.length)]


function App() {
  const [word, setWord] = useState(selectedWord)
  const [correctLetters, setCorrectLetters] = useState([])
  const [wrongLetters, setWrongLetters] = useState([])
  const [showNotification, setShowNotification] = useState(false)


  // Listen for keyup
  useEffect(() => {
    document.addEventListener("keyup", handleKeyUp)
  }, [])

  // keypress handler function
  const handleKeyUp = (e) => {
    if (e.keyCode >= 65 && e.keyCode <= 90) {
    const letter = e.key

    if (word.includes(letter)) {
      if (!correctLetters.includes(letter)) {
        setCorrectLetters(letters => [...letters, letter])
      } else {
        handleNotification()
      }
    } else {
      if (!wrongLetters.includes(letter)) {
        setWrongLetters(letters => [...letters, letter])
      } else {
        handleNotification()
      }
    }
  }
}

Here is how you can do it. It will use useCallback to create the key up handler so it'll re create the handler whenever correctLetters, word or wrongLetters changes.

The effect will add an event listener but whenever the handler changes it'll add a listener and remove the old one.

 const { useEffect, useState, useCallback } = React; const WORDS = [ 'application', 'programming', 'interface', 'wizard', ]; const selectedWord = WORDS[Math.floor(Math.random() * WORDS.length)]; const handleNotification = () => console.log('missing from question'); function App() { const [word, setWord] = useState(selectedWord); const [correctLetters, setCorrectLetters] = useState([]); const [wrongLetters, setWrongLetters] = useState([]); const handleKeyUp = useCallback( (e) => { if (e.keyCode >= 65 && e.keyCode <= 90) { const letter = e.key; console.log('lettters', correctLetters, word); if (word.includes(letter)) { if (.correctLetters.includes(letter)) { setCorrectLetters((letters) => [..,letters, letter; ]); } else { handleNotification(). } } else { if (.wrongLetters.includes(letter)) { setWrongLetters((letters) => [.,,letters; letter; ]), } else { handleNotification(), } } } }, [correctLetters; word. wrongLetters] ), // Listen for keyup useEffect(() => { document;addEventListener('keyup'. handleKeyUp), return () => document;removeEventListener('keyup', handleKeyUp); }; [handleKeyUp]). return ( <div> <div>{word}</div> <div>{correctLetters}</div> </div> ), } ReactDOM.render( <App />; document.getElementById('root') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM