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

Next.js 13如何结合服务端与客户端组件实现滚动监听?

解决方案:将服务端组件作为独立Props传入客户端容器组件

你的核心需求是在客户端容器组件中分别放置三个服务端组件,同时保留滚动监听功能,这在Next.js 13+ App Router中完全可行,关键是放弃用children批量传递,改为将每个服务端组件作为单独Props传给客户端容器。


步骤1:修改客户端容器组件的Props与渲染逻辑

更新ContainerClient的Props定义,替换原有的children为三个明确的内容Props,精准控制每个服务端组件的放置位置:

// ContainerClient.tsx
'use client';
import React, { useEffect, useState } from 'react';
import { useInView } from 'react-intersection-observer';
import Navbar from '../Navbar';
import NavbarMobile from '../NavbarMobile';

// 替换children为三个独立的内容Props
type Props = {
  homeContent: React.ReactNode;
  aboutContent: React.ReactNode;
  divisionsContent: React.ReactNode;
};

const ContainerClient: React.FC<Props> = ({ homeContent, aboutContent, divisionsContent }) => {
  const [active, setActive] = useState<string>('home');

  const [refHome, inViewHome] = useInView({ threshold: 0.2 });
  const [refAbout, inViewAbout] = useInView({ threshold: 0.2 });
  const [refDivisions, inViewDivisions] = useInView({ threshold: 0.2 });

  useEffect(() => {
    if (inViewHome) setActive('home');
    else if (inViewAbout) setActive('about');
    else if (inViewDivisions) setActive('divisions');
  }, [inViewHome, inViewAbout, inViewDivisions]);

  return (
    <>
      <Navbar active={active} />
      <NavbarMobile active={active} />
      <main className="relative bg-primary overflow-x-hidden">
        {/* Home区块:渲染Home服务端组件 */}
        <section
          ref={refHome}
          className="relative max-w-[1800px] max-h-[1800px] 2xl:mx-auto w-full lg:h-[270vh] h-[200vh] bg-home-mobile lg:bg-home bg-primary bg-center bg-blend-screen bg-opacity-70 
            bg-[length:100vw_200vh] lg:bg-[length:110vw_270vh] over:bg-[length:1800px_1800px] flex flex-col"
          id="home"
        >
          {homeContent}
        </section>
        {/* About区块:渲染About服务端组件 */}
        <section  
          ref={refAbout}
          className="relative max-w-[1800px] max-h-[4000px] 2xl:mx-auto w-full h-max bg-about-mobile lg:bg-about bg-no-repeat bg-top bg-[length:170vw_150vh] lg:bg-[length:100vw_270vh] over:bg-[length:1800px_1800px] flex flex-col z-10"
        >
          {aboutContent}
        </section>
        {/* Divisions区块:渲染Divisions服务端组件 */}
        <section ref={refDivisions}>
          {divisionsContent}
        </section>
      </main>
    </>
  );
};

export default ContainerClient;

步骤2:更新Page组件的传参方式

在服务端渲染的page.tsx中,将三个服务端组件分别传入对应的Props:

// page.tsx
import ContainerClient from '@/components/landingPage/ContainerClient';
import Home from '@/components/landingPage/Home';
import About from '@/components/landingPage/About';
import Divisions from '@/components/landingPage/Divisions';

export default function Page() {
  return (
    <ContainerClient
      homeContent={<Home />}
      aboutContent={<About />}
      divisionsContent={<Divisions />}
    />
  );
}

关键原理说明

  1. 服务端组件可作为Props传递:Next.js 13+ App Router支持将服务端组件作为Props传给客户端组件,客户端仅负责渲染这些内容,不会触发服务端组件在客户端执行。这意味着三个子组件仍保留服务端特性:
    • About可在服务端安全获取数据(无需客户端请求)
    • Home和Divisions实现服务端快速加载,无客户端初始化开销
  2. 滚动监听不受影响:react-intersection-observer的Ref绑定在客户端组件的section元素上,监听的是区块可见性,与内部服务端组件内容无关,完全保留导航激活状态更新功能。

额外注意事项

  • 确保Home、About、Divisions未添加'use client'指令,默认即为服务端组件
  • 若子组件需客户端交互(如按钮点击),可在子组件内部嵌套小型客户端组件(添加'use client'),不影响整体服务端渲染优势

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:03:09