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

245
Visualizações
How to Deal with JavaScript Closure when Using Async Code from a Separate Function

I'm trying to create a cleanup function for my useEffect and update the variable cancelRequest that is being used by the code from my getAllTweets() function.

let cancelRequest = false;

useEffect(() => {
    if (!url) {
        dispatch({ type: "IDLE" });
        return;
    }

    getAllTweets();

    return function cleanup() {
        cancelRequest = true;
    };
}, [state.page]);

...

function getAllTweets() {
    axiosConfig
        .get(`${url}?page=${state.page}`)
        .then((response) => {
            if (cancelRequest) {
                dispatch({ type: "IDLE" });
                return;
            } else if (state.page !== -1) {
                state.page === 1
                    ? dispatch({ type: "LOADED", payload: response.data.data })
                    : dispatch({
                            type: "LOADED",
                            payload: [...state.tweets, ...response.data.data],
                      });
            }

            ...
        })

        ...
}

But I think the variable wasn't being updated as I'm still getting the Can't perform a React state update on an unmounted component warning on my app when I'm trying to exit while it was fetching data.

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

0

useReducer performs the same sort of role as useState - it stores state but is said to be useful for handling complex state logic. But still, if you use useReducer in a component, and that component becomes unmounted, you shouldn't call dispatch again, because it corresponds to state in that component only. Even just doing

dispatch({ type: "IDLE" });

will produce a React warning.

But there's another potential issue. cancelRequest is a component-scoped variable, which means there will be a separate binding for that variable each render - so reassigning cancelRequest in only a single render may not be enough in case there's also an async action going on from a prior render. Use a ref instead, which is persistent across all renders. The cleanup to change the ref should be in a separate useEffect(.., []) so that it'll run only when the component unmounts, rather than every time the page changes.

const cancelReqestRef = useRef();
useEffect(() => {
    // When unmounting, and only when unmounting, change the ref
    return () => cancelReqestRef.current = true;
}, []);
useEffect(() => {
    if (!url) {
        dispatch({ type: "IDLE" });
        return;
    }
    getAllTweets();
}, [state.page]);

...

function getAllTweets() {
    axiosConfig
        .get(`${url}?page=${state.page}`)
        .then((response) => {
            if (cancelReqestRef.current) {
                // DO NOT update state here with dispatch, just return
                return;
            } else if (state.page !== -1) {
                state.page === 1
                    ? dispatch({ type: "LOADED", payload: response.data.data })
                    : dispatch({
                            type: "LOADED",
                            payload: [...state.tweets, ...response.data.data],
                      });
            }

            ...
        })

        ...
}
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