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

Next.js 13客户端组件实现锚点跳转及服务端数据获取的问题

解决方案

核心思路

把交互逻辑(锚点跳转)和数据获取逻辑拆分为独立组件:交互部分用客户端组件(需'use client'指令),数据获取部分用服务端组件(默认就是,无需特殊指令),再通过根页面(服务端组件)整合两者——因为服务端组件可以渲染客户端组件,完美适配你的需求。


步骤1:将头部菜单改为客户端组件

头部需要处理点击事件和DOM滚动,必须作为客户端组件。添加'use client'指令后,即可安全操作DOM实现平滑跳转:

'use client';

export default function Header() {
  const scrollToSection = (sectionId) => {
    const targetElement = document.getElementById(sectionId);
    if (targetElement) {
      targetElement.scrollIntoView({ behavior: 'smooth' });
    }
  };

  return (
    <header className="header">
      <nav>
        <button onClick={() => scrollToSection('about-section')}>关于我们</button>
        {/* 其他菜单项,比如首页、联系我们等 */}
      </nav>
    </header>
  );
}

步骤2:将About组件改为服务端组件

About需要用Prisma读取数据库,必须在服务端运行。直接写async/await逻辑即可,无需'use client':

首先确保PrismaClient以单例模式创建(避免重复实例化),在prisma/client.js中:

import { PrismaClient } from '@prisma/client';

const prisma = global.prisma || new PrismaClient();

if (process.env.NODE_ENV !== 'production') global.prisma = prisma;

export default prisma;

然后编写About组件:

import prisma from './prisma/client';

export default async function About() {
  // 直接在服务端从数据库拉取数据
  const aboutData = await prisma.about.findFirst();

  return (
    <section id="about-section" className="about-section">
      <h2>关于我们</h2>
      {aboutData ? (
        <p>{aboutData.content}</p>
      ) : (
        <p>暂无关于我们的内容</p>
      )}
    </section>
  );
}

步骤3:在根页面整合组件

App Router中的page.js默认是服务端组件,可以直接导入并渲染客户端的Header和服务端的About:

import Header from './Header';
import About from './About';
import Home from './Home'; // 你的首页区块组件(可按需设为客户端/服务端)
import Contact from './Contact'; // 联系我们区块组件

export default async function LandingPage() {
  // 如果有其他服务端数据需求,也可在这里统一处理
  return (
    <div className="landing-page">
      <Header />
      <Home />
      <About />
      <Contact />
    </div>
  );
}

为什么这样可行?

  • 服务端组件(About、page.js)运行在服务器,不会暴露Prisma代码到浏览器,解决了PrismaClient无法在浏览器运行的问题。
  • 客户端组件(Header)运行在浏览器,负责处理交互逻辑,避开了客户端组件不能用async/await的限制。
  • 服务端组件允许渲染客户端组件,完全符合Next.js 13 App Router的组件嵌套规则。

内容的提问来源于stack exchange,提问作者Angga Ari Wijaya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 21:30:26