如何从函数内部的useState获取值

时间:2019-09-28 13:17:45

标签: reactjs react-hooks

我正在尝试构建Hanging man游戏,并希望从checkMatchLetter函数内的useState获取值,但是不确定这是否可行以及我做错了什么。...

import React, { useState, useEffect } from 'react';
import { fetchButton } from '../actions';
import axios from 'axios';
import 'babel-polyfill';

const App = () => {
    const [word, setWord] = useState([]);
    const [underscore, setUnderscore] = useState([]);
    const [data, setData] = useState([]);

    useEffect(() => {
        const runEffect = async () => {
            const result = await axios('src/api/api.js');
            setData(result.data)
        }
        runEffect();
    }, []);

    const randomWord = () => {
        const chosenWord = data[Math.floor(Math.random() * data.length)];
        replaceLetter(chosenWord.word);
    }

    const replaceLetter = (string) => {
      
        let getString = string; // here it shows a valid string.
        setWord(getString);
        let stringToUnderScore = getString.replace(/[a-z]/gi, '_');
        setUnderscore(stringToUnderScore);
    }

    useEffect(() => {
        const checkLetter = (event) => {
            if(event.keyCode >= 65 && event.keyCode <= 90) {
                checkMatchLetter(word, String.fromCharCode(event.keyCode).toLowerCase());
            }
        };

        document.addEventListener('keydown', checkLetter);
        return () => {
            document.removeEventListener('keydown', checkLetter);
        }
    }, []);

    const checkMatchLetter = (keyButton) => {
        console.log(keyButton);
        let wordLength = word.length;
        console.log(wordLength); // here it outputs '0'
        /// here I want word of useState here....
    }

    return (
        <div>
            <p>{word}</p>
            <p>{underscore}</p>
            <button onClick={randomWord}></button>
        </div>
    )
}

export default App;

之所以要在此函数中获取该值,是因为我可以将单击的按键(a-z)与当前所选单词进行比较。如果其他功能有问题,请随时在下面分享您的反馈。

1 个答案:

答案 0 :(得分:1)

您正在使用useEffect效果在组件渲染函数内部定义的变量,并且该钩子的deps中缺少该变量。始终包括您需要的部门(我强烈建议使用皮棉规则react-hooks/exhaustive-deps)。当您将checkMatchLetter添加到dep中时,效果中将始终具有该函数的最新实例,而不是像现在一样始终使用第一个渲染中的旧版本。

useEffect(() => {
    const checkLetter = (event) => {
        if(event.keyCode >= 65 && event.keyCode <= 90) {
            checkMatchLetter(word, String.fromCharCode(event.keyCode).toLowerCase());
        }
    };

    document.addEventListener('keydown', checkLetter);
    return () => {
        document.removeEventListener('keydown', checkLetter);
    }
}, [checkMatchLetter, word]);

此更改将使效果在每个渲染上运行。为了解决这个问题,您可以记住您的回调。但是,这是蠕虫的新罐头。