Sé que ya hay varias preguntas similares aquí, pero no puedo ver qué solución asincrónica debo hacer para que esto funcione.
Tengo un sitio web de Next.js donde quiero mostrar un video, pero solo cuando estamos en el escritorio. No quiero que el video esté allí en el móvil para evitar que el usuario lo descargue en primer lugar, y para hacerlo, escribí mi propio enlace de React para realizar un seguimiento del tamaño de la ventana.
Puedo usar isDesktop en mi código y todo funciona, y dado que todavía estoy en la fase de desarrollo, agregué el oyente de cambio de tamaño de ventana para poder probar fácilmente las cosas simplemente cambiando el tamaño de mi ventana en lugar de recargar la página cada vez.
Todo funciona como se esperaba, excepto por este temido mensaje:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.que me está volviendo loco. tengo este codigo:
import { useState, useEffect } from 'react'; export function useWindowSize() { const isBrowser = typeof window !== 'undefined'; const [isDesktop, setIsDesktop] = useState<boolean>(false); function update() { setIsDesktop(window.innerWidth >= 768); } useEffect(() => { if (isBrowser) { update(); window.addEventListener('resize', update, false); return () => { window.removeEventListener('resize', update, false); }; } }, [isBrowser]); return { isDesktop }; } y tan pronto como comento la llamada de update en useEffect , el mensaje desaparece. Pero luego ya no obtengo el estado inicial (es decir, no mostrará el video en la página de mi escritorio hasta que comience a cambiar el tamaño de la ventana, y eso no es lo que debería suceder).
El problema es que está llamando condicionalmente a la función de limpieza useEffect, siempre debe ser estática. Intente poner la condición isBrowser dentro de la función de limpieza
useEffect(() => { if (isBrowser) { update(); window.addEventListener('resize', update, false); } return () => { isBrowser && window.removeEventListener('resize', update, false); }; }, [isBrowser]);