Как получить значение из useState внутри функции - PullRequest
1 голос
/ 28 сентября 2019

Я пытаюсь построить игру Hanging man и хочу получить значение из useState внутри функции checkMatchLetter, но не уверен, возможно ли это и что я сделал неправильно ....

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;

Причина, по которой я хочу получить это значение внутри этой функции, заключается в том, что я могу сравнить нажатую кнопку (az) с текущим выбранным словом.И если что-то не так с другими функциями, пожалуйста, не стесняйтесь поделиться своим мнением здесь ниже.

1 Ответ

0 голосов
/ 29 сентября 2019

Вы используете переменную, определенную внутри функции рендеринга компонента в эффекте useEffect, и эта переменная отсутствует в ловушке ловушки.Всегда включайте нужные вам deps (я настоятельно рекомендую правило lint react-hooks/exhaustive-deps).Когда вы добавляете checkMatchLetter в deps, у вас всегда будет самый новый экземпляр функции внутри вашего эффекта вместо того, чтобы всегда использовать старую версию из первого рендера, как вы делаете сейчас.

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]);

Это изменение будетзаставить эффект работать на каждом рендере.Чтобы исправить это, вы можете запомнить ваши обратные вызовы.Однако это новая банка червей.

...