React/Gatsby 条件渲染时短暂加载错误div的解决方法问询
解决方案
- 优先使用CSS媒体查询替代JS条件渲染(最优方案)
你遇到的闪现是Gatsby静态渲染的特性导致的:首屏HTML是服务端生成的,React客户端hydrate完成前不会执行JS逻辑,你的windowDimension初始值为null,此时null <=740判断结果为false,会先渲染桌面端导航,等hydrate完成拿到窗口宽度后才切换为移动端菜单,就出现了短暂闪现。
用CSS媒体查询完全避开了JS执行延迟的问题,修改步骤如下:
- 调整你的
navlinks.module.scss,新增两类显隐控制样式:
.mobile-menu { display: none; @media (max-width: 740px) { display: block; } } .desktop-nav { display: block; @media (max-width: 740px) { display: none; } }
- 移除JS里的宽度判断和resize监听逻辑,直接渲染两套导航,由CSS控制显隐即可:
import React from "react" import * as navlinksStyles from "./navlinks.module.scss" const NavLinks = () => { return ( <div className={navlinksStyles.wrapper}> {/* 移动端菜单 */} <div className={navlinksStyles.mobileMenu}> <h1 className={navlinksStyles.menu}>menu</h1> </div> {/* 桌面端导航 */} <div className={`${navlinksStyles.desktopNav} ${navlinksStyles.navlinksWrapper}`}> <ul> <li>About</li> <li>Services</li> <li>Frames</li> <li>Lenses</li> <li>Locations</li> <li>Mailbox</li> </ul> </div> </div> ) } export default NavLinks
这个方案不需要JS监听窗口事件,性能更好,也完全不会出现闪现问题。
- 若必须保留JS控制逻辑,可增加初始化加载态
如果业务场景必须用JS动态判断渲染,可以增加客户端初始化判断,未拿到窗口宽度前不渲染导航内容:
import React, { useEffect, useState } from "react" import * as navlinksStyles from "./navlinks.module.scss" const NavLinks = () => { const [windowDimension, setWindowDimension] = useState(null) const isClient = typeof window !== 'undefined' useEffect(() => { setWindowDimension(window.innerWidth) function handleResize() { setWindowDimension(window.innerWidth) } window.addEventListener("resize", handleResize) return () => window.removeEventListener("resize", handleResize) }, []) // 未完成客户端初始化时返回空,避免错误渲染导致闪现 if (!isClient || windowDimension === null) return null const isMobile = windowDimension <= 740 return ( <div className={navlinksStyles.wrapper}> {isMobile ? ( <div> <h1 className={navlinksStyles.menu}>menu</h1> </div> ) : ( <div className={navlinksStyles.navlinksWrapper}> <ul> <li>About</li> <li>Services</li> <li>Frames</li> <li>Lenses</li> <li>Locations</li> <li>Mailbox</li> </ul> </div> )} </div> ) } export default NavLinks
也可以给外层wrapper加初始opacity:0的样式,等初始化完成后再设置为opacity:1,搭配过渡动画体验更流畅。
内容的提问来源于stack exchange,提问作者thomtheetoad
相关产品推荐
相关产品推荐

