Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

115
Visualizações
react function not using updated state

My handleKeyUp function is not using any of the new values in the state. In the function, playingTrackInd is always equal to -1, even when the state has been updated for playingTrackInd to be something else.

import React, { useEffect, useRef, useState } from 'react';
import { Container } from 'react-bootstrap';

export interface Track {
    artist: string,
    title: string,
    uri: string,
    albumUrl: string,
    previewUrl?: string,
}

export default function Dashboard() {
    const [playingTrackInd, setPlayingTrackInd] = useState<number>(-1);
    const tracks = useRef<Array<Track>>([]);
   
    // add keylistener
    useEffect(() => {
        document.addEventListener('keyup', handleKeyUp);

    }, []);

    // this function always has playingTrackInd as -1, even when the state has been updated by setPlayingTrackInd
    function handleKeyUp(e: any) {
        if (e.keyCode === 39) {
            // right arrow pressed
            if (playingTrackInd === tracks.current.length - 1) {
                getRandomTrack(() => setPlayingTrackInd(prevInd => prevInd + 1));
            }
            else {
                setPlayingTrackInd(prevInd => prevInd + 1)
            }

        }
        else if (e.keyCode === 37) { // left arrrow key pressed
            if (playingTrackInd > 0) {
                setPlayingTrackInd(prevInd => prevInd - 1);
            }
        }
    }

    // function that gets random track and adds it to tracks
    function getRandomTrack(callback?: Function) {
        getRandomTrackFromApi().then((track) => {
            tracks.current.push(track);
            if (callback) {
                callback();
            }
        })
    }

    // get first random track and set playingTrackInd to 0. This happens as soon as the component is loaded
    useEffect(() => {
        if (playingTrackInd === -1) { 
            getRandomTrack(() => setPlayingTrackInd(0));
        }
        getRandomTrack();
        getRandomTrack();


        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    return (
        (component that depends on tracks[playingTrackInd])
    );
}

I can't understand why playingTrackInd is always -1 only in the handleKeyUp function. Everywhere else, including the return statement, it is the proper value. Thanks.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

The problem lies in the effect below:

    useEffect(() => {
        document.addEventListener('keyup', handleKeyUp);
    }, []);

As you can see, you're registering handleKeyUp once (Effect is triggered once, on mount, because deps array is empty). handleKeyUp remembers last value of playingTrackInd via Closure (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures). When playingTrackInd is updated, component rerenders, new handleKeyUp function is created, but you've already registered your handleKeyUp that remembers old value, and you're not updating that listener.

You can fix that issue by for example by passing handleKeyUp to dependency array like below:

    useEffect(() => {
        document.addEventListener('keyup', handleKeyUp);
        return () => {
          document.removeEventListener('keyup', handleKeyUp);
        }
    }, [handleKeyUp]);

Don't forget to remove listener before new listener is going to be registered. Solution is not ideal, because handleKeyUp function is created every render. Same issue exists in your second useEffect hook.

I strongly recommend to wrap your functions into useCallback (https://reactjs.org/docs/hooks-reference.html#usecallback) and pass all dependencies in deps arrays. That way your fuctions won't be created every render, but only when their dependencies change.

Another thing is that there's an eslint rule that will help you track all required deps in deps arrays, check exhaustive-deps https://reactjs.org/docs/hooks-rules.html

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda