【发布时间】:2020-02-24 18:11:15
【问题描述】:
基于 window.innerWidth 的组件条件渲染似乎无法在基于 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 阈值,然后它可以在桌面和移动设备上完美地工作,但不是在加载时。
【问题讨论】:
标签: javascript reactjs jsx gatsby server-side-rendering