我正在尝试根据窗口的宽度渲染移动导航或常规导航栏。部署到netlify时,出现错误,即服务器端渲染期间窗口不可用。我阅读了有关该问题的gatsby docs文档,并且了解到这种情况的发生,但是由于无法在useEffect中使用useState,否则我无法弄清楚重组的正确方法,否则我将处理变量的作用域。任何帮助将不胜感激!
这是gatsby文档:https://www.gatsbyjs.com/docs/debugging-html-builds/
const Layout = ({ children}) => {
const width = useWindowSize()
let navbar;
if (width > 936) {
navbar = <NavBar />
} else {
navbar = <MobileNav />
}
return (
<OverflowHidden>
{navbar}
<main>{children}</main>
<Footer/>
</OverflowHidden>
)
}
const useWindowSize = () => {
const [size, setSize] = useState(window.innerWidth)
useEffect(() => {
const handleResize = () => {
setSize(window.innerWidth)
}
window.addEventListener('resize', handleResize)
}, [])
return size
}
const OverflowHidden = styled.div`
overflow-x: hidden;
height: 100%;
`
export default Layout
答案 0 :(得分:3)
无论如何,您都无法在编译时测量浏览器视口服务器端的大小,因此只需设置默认值/后备值即可。另外,您需要确保清除在卸载组件时绑定的事件。
我也建议在此处添加一个防反跳例程-并非所有浏览器都会为您执行此操作,并且在调整大小的浏览器中不断更新布局通常会导致性能下降。
总的来说,你会得到这样的东西:
const useWindowSize = (initialState = "100%", { ttl = 100 } = {}) => {
// initialState is used before the component mounts client-side
const [height, setHeight] = useState(initialState)
useEffect(() => {
const calculateHeight = debounce(() => {
setHeight(window.innerHeight)
}, ttl)
calculateHeight()
window.addEventListener("resize", calculateHeight)
return () => {
// deregister event listener on component dismount
window.removeEventListener("resize", calculateHeight)
}
}, [ttl])
return height
}