NextJS配合Bootstrap移动端导航栏点击跳转后仍展开怎么解决
解决方案
核心逻辑
Next.js的Link组件走客户端路由跳转,不会触发页面重载,Bootstrap原生脚本无法感知路由变化,因此展开的移动端菜单不会自动重置状态。最优方案是直接调用Bootstrap官方提供的Collapse组件API手动关闭菜单,完全适配客户端路由逻辑,不会和Bootstrap原生交互冲突。
完整修改后代码
import { useEffect, useRef } from 'react' import Link from 'next/link' import Image from 'next/image' import { ArrowDownCircle } from 'react-bootstrap-icons' import { Collapse, Dropdown } from 'bootstrap' import logo from '../public/images/logo.gif' import styles from '../styles/Navbar.module.scss' const Navbar = () => { // 存储折叠菜单DOM节点和实例 const collapseRef = useRef(null) const collapseInstanceRef = useRef(null) // 关闭菜单通用方法 const closeMenu = () => { // 仅在移动端视图下执行关闭逻辑 if (window.innerWidth < 768 && collapseInstanceRef.current) { collapseInstanceRef.current.hide() } // 关闭所有打开的下拉菜单 document.querySelectorAll('.dropdown-menu.show').forEach(el => { const dropdownInstance = Dropdown.getInstance(el.parentElement) dropdownInstance?.hide() }) } useEffect(() => { // 初始化Collapse实例 if (collapseRef.current) { collapseInstanceRef.current = new Collapse(collapseRef.current, { toggle: false }) } }, []); return ( <nav id="navbar" className="navbar navbar-expand-md navbar-light container"> <div> <Link href="/" prefetch={false}><a className="navbar-brand" onClick={closeMenu}> <Image src={logo} alt="Logo" layout="intrinsic" width={200} height={50} priority={true} /> </a></Link> </div> <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span> </button> <div className="collapse navbar-collapse" id="navbarNav" ref={collapseRef}> <ul className={`${styles.navLink} navbar-nav ms-auto`}> <li className="nav-item"> <Link href="/" prefetch={false}><a className={`${styles.link} nav-link`} aria-current="page" onClick={closeMenu}>Home</a></Link> </li> <li className="nav-item"> <Link href="/about" prefetch={false}><a className={`${styles.link} nav-link`} onClick={closeMenu}>About</a></Link> </li> <li className="nav-item dropdown"> <a className={`${styles.link} nav-link`} id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">Services <ArrowDownCircle className="ms-1" /></a> <ul className="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <li><Link href="/web-design"><a className="dropdown-item" onClick={closeMenu}>Web Design</a></Link></li> <li><Link href="/web-development"><a className="dropdown-item" onClick={closeMenu}>Web Development</a></Link></li> <li><Link href="/ecommerce"><a className="dropdown-item" onClick={closeMenu}>eCommerce</a></Link></li> </ul> </li> <li className="nav-item"> <Link href="/faq" prefetch={false}><a className={`${styles.link} nav-link`} onClick={closeMenu}>FAQ</a></Link> </li> <li className="nav-item"> <Link href="/contact" prefetch={false}><a className={`${styles.link} nav-link`} onClick={closeMenu}>Contact</a></Link> </li> </ul> </div> <style jsx>{` a { background: none; } a:hover { background: none; } `}</style> </nav> ); } export default Navbar;
改动说明
- 新增
useRef存储折叠菜单的DOM节点和Bootstrap Collapse实例,避免重复初始化 - 封装
closeMenu通用方法,适配移动端视图判断,同时支持关闭折叠面板和下拉菜单 - 给所有导航链接绑定
onClick={closeMenu}事件,点击跳转时自动触发菜单关闭 - 移除了原来的动态import加载Bootstrap脚本逻辑,改为直接导入Bootstrap组件类,调用官方API更稳定
内容的提问来源于stack exchange,提问作者Roy Sheppard
相关产品推荐
相关产品推荐

