Le rendu conditionnel des composants basés sur window.innerWidth
Semble ne pas fonctionner comme prévu juste dans le Production Construction du site Web basé sur Gatsby.
Le crochet que j'utilise pour vérifier la largeur de la fenêtre, avec la vérification supplémentaire de la fenêtre Global pour éviter les erreurs de construction de la production de gatsby-nœud, est la suivante:
import { useState, useEffect } from 'react'
const useWindowWidth = () => {
const windowGlobal = typeof window !== 'undefined'
if(windowGlobal) {
const [width, setWidth] = useState(window.innerWidth)
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth)
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
})
return width
}
}
export default useWindowWidth
Puis dans mon composant réel, je fais ce qui suit:
IndexPage.Booking = () => {
const windowWidth = useWindowWidth()
return (
<div className="section__booking__wrapper">
{ windowWidth <= mediaQueries.lg && <IndexPage.Cta /> }
<div className="section__booking-bg" style={{ backgroundImage: `url(${bg})` }}>
{ windowWidth > mediaQueries.lg && <IndexPage.Cta /> }
</div>
</div>
)
}
Cela fonctionne comme il se doit en development
mais le production La construction échoue à rendre:
<div className="section__booking-bg" style={{ backgroundImage: `url(${bg})` }}>
Lors du redimensionnement de la fenêtre sous le Mediaqueries.lg (1024), il déclenche ensuite le comportement normal réel ou le rendu de manière conditionnelle des versions mobiles et du bureau du composant.
À Doublecheck Si c'était parce que le rendu déclenche uniquement l'événement resize
(ce qu'il ne fonctionne pas comme il fonctionne sur la charge dans development
environnement), je suis aussi simplement, de l'intérieur console.log()
la valeur de retour et elle est imprimée, in production correctement sur charge.
Il n'y a pas non plus d'erreurs ni d'avertissements dans le Production ou development
Construire.
Modifier selon la suggestion de @Phillip
const useWindowWidth = () => {
const isBrowser = typeof window !== 'undefined'
const [width, setWidth] = useState(isBrowser ? window.innerWidth : 0)
useEffect(() => {
if (!isBrowser) return false
const handleResize = () => setWidth(window.innerWidth)
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
})
return width
}
Il fonctionne désormais lorsque vous le redimensionnez, une fois, sous le seuil Mediaqueries.lg, puis cela fonctionne parfaitement sur le bureau et le mobile, mais pas sur la charge.
Ne pas appeler les crochets à l'intérieur des boucles, des conditions ou des fonctions imbriquées ( de React docs )
Réagir des crochets DOIT Exécutez exactement le même ordre sur Tous Rendu. Déplacez votre état en useEffect
rappel:
useEffect(() => {
if (typeof window === 'undefined') return;
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize)
};
});