Mel*_*uso 8 javascript jsx reactjs server-side-rendering gatsby
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
Run Code Online (Sandbox Code Playgroud)
然后在我的实际组件中,我执行以下操作:
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>
)
}
Run Code Online (Sandbox Code Playgroud)
它可以正常工作,development但生产版本无法呈现:
<div className="section__booking-bg" style={{ backgroundImage: `url(${bg})` }}>
Run Code Online (Sandbox Code Playgroud)
当调整 mediaQueries.lg (1024) 下面的窗口大小时,它会触发实际的正常行为或有条件地呈现组件的移动和桌面版本。
要仔细检查是否是因为渲染仅在resize事件上触发(它不会因为它在development环境中加载而起作用)我也很简单,从钩子console.log()内返回值并在生产中打印在加载时正确。
在生产或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
}
Run Code Online (Sandbox Code Playgroud)
它现在只在您调整大小时在 mediaQueries.lg 阈值下工作一次,然后它可以在桌面和移动设备上完美运行,但不能在加载时运行。
我遇到了与此类似的问题,还没有找到解决方案,但可以解决。将以下内容放在渲染的开头:
if (typeof window === `undefined`) {
return(<></>);
}
Run Code Online (Sandbox Code Playgroud)
我认为正在发生的是 Gatsby 正在使用基于窗口宽度(将为 0 / 未定义)的样式构建页面。然后它不会在页面加载后更新 DOM 中的样式,因为它认为它已经执行了该操作。我认为这可能是 Gatsby 中的一个小错误?
无论哪种方式,上述内容都会在构建期间将您的组件呈现为空白,从而迫使它在页面加载时完全遵守所有逻辑。希望这提供了一个解决方案,尽管不是一个令人满意/完整的解释:)
Don\xe2\x80\x99t 在循环、条件或嵌套函数内调用 Hooks(来自 React 文档)
\n\nReact Hooks必须在每次渲染上以完全相同的顺序运行。将您的条件移入useEffect回调中:
useEffect(() => {\n if (typeof window === \'undefined\') return;\n\n const handleResize = () => setWidth(window.innerWidth);\n window.addEventListener(\'resize\', handleResize);\n return () => {\n window.removeEventListener(\'resize\', handleResize)\n };\n});\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
5169 次 |
| 最近记录: |