Estoy tratando de crear una función de limpieza para mi useEffect y actualizar la variable cancelRequest que está siendo utilizada por el código de mi función getAllTweets() .
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], }); } ... }) ... } Pero creo que la variable no se estaba actualizando porque sigo recibiendo la advertencia Can't perform a React state update on an unmounted component en mi aplicación cuando intento salir mientras estaba obteniendo datos.
useReducer realiza el mismo tipo de función que useState : almacena el estado, pero se dice que es útil para manejar la lógica de estado compleja. Pero aún así, si usa useReducer en un componente y ese componente se desmonta, no debe volver a llamar a dispatch, porque corresponde al estado en ese componente solamente . Incluso simplemente haciendo
dispatch({ type: "IDLE" });producirá una advertencia de reacción.
Pero hay otro problema potencial. cancelRequest es una variable de ámbito de componente, lo que significa que habrá un enlace separado para esa variable en cada procesamiento, por lo que reasignar cancelRequest en un solo procesamiento puede no ser suficiente en caso de que también haya una acción asíncrona en curso desde un procesamiento anterior. En su lugar, use una referencia, que es persistente en todos los renderizados. La limpieza para cambiar la referencia debe estar en un useEffect(.., []) separado para que se ejecute solo cuando el componente se desmonte, en lugar de cada vez que cambie la página.
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], }); } ... }) ... }