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

NextJS 14 App Router:需Params时如何拆分客户端/服务端组件?

解决方案:拆分服务端与客户端组件

解决这个冲突的核心是把服务端逻辑和客户端逻辑拆分开——利用Next.js 14 App Router的默认规则:page.tsx默认是服务端组件,能直接获取路由params,不需要依赖客户端的useParams;而需要React Hooks(比如GraphQL查询钩子)的逻辑,单独放到客户端组件里。

步骤1:改造服务端页面组件(app/presentation/[id]/page.tsx)

去掉'use client'标记,直接从函数参数中获取params,保留metadata并渲染客户端子组件:

import { Metadata } from 'next';
import PresentationContent from './PresentationContent';

export const metadata: Metadata = {
  title: 'Presentation'
};

export default function PresentationPage({ params }: { params: { id: string } }) {
  const { id } = params;
  
  if (!id) throw new Error('Query parameter missing');
  if (Array.isArray(id)) throw new Error("Query parameter shouldn't be an array");

  return <PresentationContent id={id} />;
}

步骤2:创建客户端逻辑组件(app/presentation/[id]/PresentationContent.tsx)

把原来需要useParams和GraphQL查询的逻辑移到这个单独的客户端组件中,加上'use client'标记:

'use client';

import { CircularProgress, Alert } from '@mui/material';
import { usePresentationContentQuery } from '@/generated/graphql';
import Presentation from '@/components/Presentation';

export default function PresentationContent({ id }: { id: string }) {
  const { loading, data } = usePresentationContentQuery({
    variables: {
      param: { name: 'id', value: id }
    }
  });

  if (loading) return <CircularProgress />;
  if (data?.presentationContent == null) {
    return (
      <Alert severity="error" elevation={0}>
        Missing data
      </Alert>
    );
  }

  return <Presentation data={data.presentationContent} />;
}

为什么这样拆分可行?

  • page.tsx作为服务端组件,天生支持直接读取路由params,同时metadata会在服务端正常生成,完全符合Next.js的要求。
  • 客户端组件PresentationContent专注处理需要React Hooks的逻辑(比如GraphQL查询、加载/错误状态),通过props接收服务端传来的id,两者职责清晰,没有冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:15:16