You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

路由切换时仅重载右侧内容的侧边栏客户端渲染问题

解决路由切换仅重载右侧内容的方案

问题根源

页面全重载主要是两个原因:

  • 布局没作为持久化的根布局,路由切换时整个布局跟着重新渲染
  • Navbar组件不是客户端组件,router.push没法触发客户端路由,只能走全页面跳转

修复步骤

1. 把布局设为持久化根布局

如果用的是Next.js App Router,把布局放在app/layout.tsx(根布局)里,这样布局会一直挂载,只有{children}部分随路由更新:

// app/layout.tsx
import { MantineProvider } from '@mantine/core';
import { AppShell } from '@mantine/core';
import HomeNavbar from './components/HomeNavbar';
import theme from './theme';

export default function RootLayout({ children }) {
  return (
    <html lang="zh-CN">
      <body>
        <MantineProvider defaultColorScheme="dark" theme={theme}>
          <AppShell navbar={{ width: 250, breakpoint: 0 }} padding={{ base: 10, sm: 15, lg: 'xl' }}>
            <HomeNavbar />
            {children}
          </AppShell>
        </MantineProvider>
      </body>
    </html>
  );
}

2. 给Navbar加上客户端组件标识

在HomeNavbar顶部加'use client',因为客户端路由相关的操作必须在客户端组件里执行:

// components/HomeNavbar.tsx
'use client'; // 这行必须加

import { AppShell, Image, Title, ColorSchemeToggle } from '@mantine/core';
import { useRouter } from 'next/navigation';
import classes from './HomeNavbar.module.css';

export default function HomeNavbar() {
  const router = useRouter();
  const data = [/* 你的链接数据 */];
  const activeLink = ''; // 你的激活状态逻辑

  return (
    <AppShell.Navbar>
      <nav className={classes.navbar}>
        <div className={classes.wrapper}>
          <div className={classes.aside}>
            <div className={classes.logo}>
              <Image src={'/logo.jpeg'} alt="Ben" width="40" height="40" />
            </div>
            {/* {mainLinks} */}
          </div>
          <div className={classes.main}>
            <Title order={4} className={classes.title}></Title>
            {data.map((link) => (
              <a
                className={classes.link}
                data-active={activeLink === link.label || undefined}
                key={link.label}
                onClick={(e) => {
                  e.preventDefault();
                  router.push(link.link);
                }}
              >
                {link.label}
              </a>
            ))}
          </div>
        </div>
        <div className={classes.footer}>
          <ColorSchemeToggle />
        </div>
      </nav>
    </AppShell.Navbar>
  );
}

3. 改用Next.js Link组件(更省心)

手动写a标签加点击事件容易出错,直接用Next.js的Link组件,它自带客户端路由功能,不用额外处理:

// 先导入Link
import Link from 'next/link';

// 替换原来的a标签:
{data.map((link) => (
  <Link
    href={link.link}
    className={classes.link}
    data-active={activeLink === link.label || undefined}
    key={link.label}
  >
    {link.label}
  </Link>
))}

这样切换路由时只会更新右侧的{children},Navbar保持不动,也不会全页面重载。


验证方法

  • 打开浏览器开发者工具的「网络」面板,切换路由时只会加载页面相关资源,不会刷新整个文档
  • 检查Navbar是否在路由切换时没有重新渲染(可以加个console.log验证)

内容的提问来源于stack exchange,提问作者user1688346

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:23:22