基于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
中正常工作,但是生产构建无法呈现:
<div className="section__booking-bg" style={{ backgroundImage: `url(${bg})` }}>
在mediaQueries.lg(1024)下调整窗口大小时,它会触发实际的正常行为或有条件地呈现该组件的移动版本和桌面版本。
要再次检查是否是因为渲染仅在resize
事件上触发(它在development
环境中加载时不会触发),我还是从钩子{{ 1}}返回值并在加载后正确地生产中将其打印出来。
产品或console.log()
版本中也没有任何错误或警告。
根据@Phillip的建议进行编辑
development
现在,只要在mediaQueries.lg阈值下调整大小,它就可以正常工作,然后在桌面和移动设备上可以完美地工作,但不会加载。
答案 0 :(得分:2)
我猜测现在回答为时已晚,但是在添加事件侦听器之前调用handleResize应该可以。这是我用于相同目的的代码:
useEffect(() => {
setWidth(window.innerWidth);
window.addEventListener("resize", () => {
setWidth(window.innerWidth);
});
return () => {
window.removeEventListener("resize", () => {});
};
}, []);
答案 1 :(得分:0)
答案 2 :(得分:0)
我有一个与此类似的问题,还没有找到解决方案,但是可以解决。将以下内容放在渲染的开头:
if (typeof window === `undefined`) {
return(<></>);
}
我认为正在发生的事情是,盖茨比正在建立一种基于窗口宽度(将为0 /未定义)的样式的页面。然后,一旦页面加载就认为它已经执行了该操作,就不会更新DOM中的样式。我认为这可能是盖茨比的一个小虫?
无论哪种方式,以上内容都会在构建过程中使您的组件空白,从而迫使它在页面加载时完全尊重所有逻辑。希望能提供一个解决方案,尽管说明不令人满意:)