Условный рендеринг компонентов на основе window.innerWidth
, похоже, не работает так, как предполагалось, только в production сборке сайта на базе Gatsby.
Крюк, который я использую для проверки ширины области просмотра, с дополнительной проверкой глобального окна, чтобы избежать ошибок производственной сборки узла Gatsby, следующий:
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
Тогда в моемФактический компонент Я делаю следующее:
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>
)
}
Он работает как надо в development
, но сборка production не может отрендериться:
<div className="section__booking-bg" style={{ backgroundImage: `url(${bg})` }}>
При изменении размераокно под mediaQueries.lg (1024) затем запускает фактическое нормальное поведение или условно отображает мобильные и настольные версии компонента.
Для двойной проверки, если это произошло, потому что рендеринг срабатывает только на событии resize
(что не работает, так как он работает с нагрузкой в development
среде). Я также просто изнутри ловушки console.log()
возвращает значение, и оно печатается, в продукция правильно при загрузке.
Также нет ошибок или предупреждений в сборке production или development
.
Редактировать в соответствии с предложением @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
}
Теперь он работает только тогда, когда вы измените его размер один раз, под порогом mediaQueries.lg, а затем он работаетбезупречно для настольных компьютеров и мобильных устройств, но не под нагрузкой.