Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

246
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda