Tengo muchos componentes, que deberían mostrarse por separado en diferentes ventanas gráficas. En el lado del cliente, está useLayoutEffect . Aquí se explica cómo usarlo sin previo aviso con SSR:
export const useLayoutEffect = typeof window !== 'undefined' && window.document && window.document.createElement ? React.useLayoutEffect : React.useEffect; Está bien si useLayoutEffect se ejecuta más tarde después del renderizado DOM inicial, cuando se carga el paquete. Pero necesito ejecutarlo antes de la primera pintura . Es necesario para el renderizado condicional usando window.matchQuery :
usarMedia.tsx:
import { useState } from 'react'; import { useLayoutEffect } from './utils'; export const useMedia = (query: string) => { const [matches, setMatches] = useState(false); useLayoutEffect(() => { const mediaObserver = window.matchMedia(query); setMatches(mediaObserver.matches); const updateMatch = (e: MediaQueryListEvent) => e.matches ? setMatches(true) : setMatches(false); if (mediaObserver.addEventListener) { mediaObserver.addEventListener('change', updateMatch); return () => mediaObserver.removeEventListener('change', updateMatch); } else { // Safari < 14 mediaObserver.addListener(updateMatch); return () => mediaObserver.removeListener(updateMatch); } }, [query]); return matches; };Otro caso idéntico es cuando necesito alternar el estado antes de que se represente el DOM.
useLayoutEffect(() => { if (window.matchMedia('(max-width: 1024px)').matches) { setOpenInfo(false); } }, []);Lo cual no es posible para SSR antes del renderizado inicial. Por ahora puedo usar el paquete https://github.com/artsy/fresnel , que parece resolver el problema, o en el futuro funciones como HTML Client Hints. ¿Quizás hay algún enfoque mejor que me perdí?