Next.js中如何实现导航栏点击切换对应组件?
实现方案:Next.js 无 react-router-dom 导航切换组件
核心思路:状态驱动的条件渲染
因为你不需要路由跳转,只是单页内的组件切换,用useState维护当前激活的导航项,配合条件渲染即可实现需求,完全适配Next.js(Pages Router/App Router都支持)。
具体代码实现
假设你的导航数据结构如下:
const navItems = [ { key: 'notifications', label: 'Notifications' }, { key: 'billing', label: 'Billing' }, { key: 'security', label: 'Security' }, ];
完整组件代码:
'use client'; // App Router 环境需要添加,Pages Router 可省略 import { useState } from 'react'; import { Navbar, Group } from '@mantine/core'; // 导入你的业务组件 import Notifications from './Notifications'; import Billing from './Billing'; import Security from './Security'; export default function AppNavbar() { // 维护当前激活的导航项key const [activeItem, setActiveItem] = useState('notifications'); // 导航项点击事件:同步激活状态与组件切换状态 const handleNavClick = (itemKey) => { setActiveItem(itemKey); }; // 根据当前激活项渲染对应组件 const renderCurrentComponent = () => { switch (activeItem) { case 'billing': return <Billing />; case 'security': return <Security />; default: return <Notifications />; } }; return ( <div style={{ display: 'flex', height: '100vh' }}> {/* Mantine 导航栏 */} <Navbar width={{ base: 250 }}> <Navbar.Section grow> <Group direction="column" gap={0}> {navItems.map((item) => ( <Navbar.Link key={item.key} active={activeItem === item.key} onClick={() => handleNavClick(item.key)} > {item.label} </Navbar.Link> ))} </Group> </Navbar.Section> </Navbar> {/* 内容区域:渲染当前激活的组件 */} <main style={{ flex: 1, padding: '24px' }}> {renderCurrentComponent()} </main> </div> ); }
优化:懒加载组件(提升首屏性能)
如果组件体积较大,可使用Next.js的dynamic实现懒加载,避免首屏加载所有组件:
'use client'; import { useState, Suspense } from 'react'; import { Navbar, Group, Loader } from '@mantine/core'; import dynamic from 'next/dynamic'; // 动态导入组件,开启懒加载 const Notifications = dynamic(() => import('./Notifications'), { ssr: false, loading: () => <Loader size="md" /> }); const Billing = dynamic(() => import('./Billing'), { ssr: false, loading: () => <Loader size="md" /> }); const Security = dynamic(() => import('./Security'), { ssr: false, loading: () => <Loader size="md" /> }); // 其余代码与上方一致,仅修改内容区域渲染: <main style={{ flex: 1, padding: '24px' }}> <Suspense fallback={<Loader size="lg" />}> {renderCurrentComponent()} </Suspense> </main>
搜索方向(便于拓展学习)
- Next.js 条件渲染组件
- Next.js dynamic 懒加载
- Mantine Navbar 状态管理
内容的提问来源于stack exchange,提问作者Lewis
相关产品推荐
相关产品推荐

