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
相关产品推荐
相关产品推荐

