如何在页面加载时设置 useState 挂钩的状态?
Posted
技术标签:
【中文标题】如何在页面加载时设置 useState 挂钩的状态?【英文标题】:How to set the state of a useState hook on page load? 【发布时间】:2022-01-16 01:22:53 【问题描述】:我正在尝试创建响应式导航。它有一个_函数:
-
在屏幕宽度上显示导航链接 > 页面加载时为 768 像素
在屏幕宽度
如果在切换到大屏幕时未在小屏幕上打开导航,请关闭导航(简单地说,如果用户在移动设备上打开导航链接,切换到更大的屏幕尺寸,然后返回移动设备,导航链接应该被隐藏再次)
我已经完成了 99% 的工作,但我认为我这样做的方式很老套,因为当我在较小的屏幕上时,导航链接会闪烁片刻,然后消失。这显然不是我想要的。
下面是一个精简的、没有样式的 sn-p 以便于调试:
export const Nav = () =>
const [showNavOnClick, setShowNavOnClick] = useState(false)
const [hamburgerOpen, setHamburgerOpen] = useState(false)
const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(true)
const toggleMenu = () =>
setShowNavOnClick(!showNavOnClick)
setHamburgerOpen(!hamburgerOpen)
useEffect(() =>
// This line solves all 3 goals, but on page load, the nav links appear, then dissapear in a split moment.
if (window.innerWidth < 768) setShowNavOnScreenSize(false)
const handleResize = () =>
if (window.innerWidth > 768)
setShowNavOnScreenSize(true)
setShowNavOnClick(false)
else if (window.innerWidth < 768)
setShowNavOnScreenSize(false)
window.addEventListener('resize', handleResize)
return () =>
window.removeEventListener('resize', handleResize)
, [])
return (
<nav>
<a href="/">Home</a>
<button onClick=toggleMenu>*</button>
<a
href="/about"
className=`$
showNavOnScreenSize ||
showNavOnClick && showNavOnScreenSize != showNavOnClick)
? 'visible'
: 'hidden'
`>
About
</a>
</nav>
)
以下是显示故障的视频:
当我添加const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(window.innerWidth >= 768)
时,我收到window is not defined
的错误
【问题讨论】:
【参考方案1】:您可以通过更改要根据宽度计算的状态的默认值而不是硬编码的true
来解决此问题:
const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(window.innerWidth >= 768)
如有必要,您可以以类似的方式为其他状态设置默认值。
编辑:或者,尝试使用布局效果,以便重新渲染是同步的:
const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(true)
useLayoutEffect(() =>
if (window.innerWidth < 768) setShowNavOnScreenSize(false)
// ...
【讨论】:
我收到window is not defined
的错误。我更新了我的帖子以显示带有该错误消息的图片。
你在使用服务器端渲染吗?
我正在使用 Next.js,但一切都在客户端呈现
看起来有效,但我不知道为什么。以上是关于如何在页面加载时设置 useState 挂钩的状态?的主要内容,如果未能解决你的问题,请参考以下文章