NextJS中useEffect钩子页面切换时检测body类失效求助
问题:NextJS导航栏检测body类失效的原因及解决办法
问题场景与代码
在我的NextJS应用的Navbar组件中,我使用useEffect钩子检测<body>标签是否包含full-width-hero类,代码如下:
Navbar.tsx
const Navbar = () => { const router = useRouter() const [fullWidthBackground, setFullWidthBackground] = useState(false) useEffect(() => { const isFullWidth = document.body.classList.contains('full-width-hero') if (isFullWidth) { setFullWidthBackground(true) } else { setFullWidthBackground(false) } }, [fullWidthBackground]) }
目前该逻辑看似正常,但当我从带有full-width-hero类的页面导航到无此类的首页/路由时,isFullWidth仍返回true。
原因分析与解决办法
核心问题
- useEffect依赖错误:你把
fullWidthBackground作为useEffect的依赖,这意味着只有当这个状态更新时,钩子才会执行。但路由切换时,这个状态并没有变化,所以useEffect不会重新触发去检测body的类。 - body类未被清理:NextJS的客户端导航中,页面组件卸载时如果没有主动移除body上的
full-width-hero类,这个类会一直保留在body标签上,导致导航后检测结果依然为true。
解决步骤
1. 修正useEffect的触发时机
将useEffect的依赖改为router.asPath,这样每次路由切换时,钩子都会重新执行,检测当前body的类:
const Navbar = () => { const router = useRouter() const [fullWidthBackground, setFullWidthBackground] = useState(false) useEffect(() => { // 简化状态赋值逻辑 const isFullWidth = document.body.classList.contains('full-width-hero') setFullWidthBackground(isFullWidth) }, [router.asPath]) // 路由路径变化时触发 }
2. 在页面组件中管理body类
在带有full-width-hero类的页面组件中,添加挂载时添加类、卸载时移除类的逻辑:
// 示例页面组件:FullWidthPage.tsx const FullWidthPage = () => { useEffect(() => { document.body.classList.add('full-width-hero') // 组件卸载时清理body类 return () => { document.body.classList.remove('full-width-hero') } }, []) return <div>全宽页面内容</div> }
这样当你离开该页面时,body上的full-width-hero类会被自动移除,导航到首页时检测结果就会是false。
内容的提问来源于stack exchange,提问作者ST80
相关产品推荐
相关产品推荐

