Estoy tratando de aprender sobre la limpieza useEffect de reaccionar.
Encontré este ejemplo sobre cómo usar la limpieza. (referencia: https://blog.logrocket.com/understanding-react-useeffect-cleanup-function/ ).
const [data, setData] = useState({}) useEffect(() => { // set our variable to true let isApiSubscribed = true; axios.get(API).then((res) => { if (isApiSubscribed) { // handle success setData(res.data) } }); return () => { // cancel the subscription isApiSubscribed = false; }; }, []);Pero me gustaría preguntar, ¿es posible que la promesa se resuelva entre el momento en que se desmonta el componente y se llama a la limpieza, lo que provoca un error, es decir, acceder al estado que se desasignó?
Si bien no puedo decirle con precisión cuándo se llama a la función de cancelación de suscripción de useEffect más específicamente que "cuando el componente está desmontado", puedo responder a su pregunta sobre las implicaciones de cuándo se llama:
¿Es posible que la promesa se resuelva entre el momento en que se desmonta el componente y se llama a la limpieza, lo que provoca un error, es decir, acceder al estado que se ha desasignado?
En el código tal como está escrito, es posible que Promise se resuelva después de que se desmonte el componente. Su isApiSubscribed es una forma de ocultar la advertencia que podría mostrarse cuando esto ocurre en el modo de desarrollo, pero no es la forma correcta de lidiar con este escenario .
Cuando esto sucede cuando reacciona se ejecuta en modo de desarrollo, es posible que reciba un mensaje de advertencia como este:
Advertencia: no se puede realizar una actualización de estado de React en un componente desmontado. Esto no es operativo, pero indica una pérdida de memoria en su aplicación. Para solucionarlo, cancele todas las suscripciones y tareas asincrónicas en el método componentWillUnmount.
El punto de este mensaje de advertencia es que debe tener cuidado de dejar de hacer el trabajo que ya no es relevante después de desmontar un componente en particular. No llamar a setData le impide actualizar el estado, pero el trabajo de la solicitud HTTP siempre se completará, incluso si el componente está desmontado. Esa es la parte que React te dice que deberías considerar cancelar.
La forma "correcta" de alterar este patrón para evitar gastar recursos innecesarios sería detener la ejecución de la solicitud HTTP cuando el componente se desmonte, lo que provocará que la promesa se rechace:
useEffect(() => { const abortController = new AbortController(); axios.get(API, { signal: abortController.signal }).then((res) => { setData(res.data) }); return () => { abortController.abort(); }; }, []); Esto asegura que no solo no llame a setData en un componente que está desmontado (que es una cantidad de trabajo relativamente trivial), sino que cancele el trabajo mucho más grande que es una solicitud HTTP (y el manejo de respuesta asociado) cuando el componente está desmontado.
Es teóricamente posible que ocurra la siguiente serie de eventos:
Pero esto requiere una sincronización precisa y el espíritu del mensaje de advertencia es evitar el escenario mucho más común: