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

Next.js 13 App目录下获取URL/参数及迁移getServerSideProps方法

Next.js 13 App目录获取postId参数的等效实现

原Pages目录逻辑参考

// pages/posts/[postId].js
export async function getServerSideProps(context) {
const { postId } = context.query;
const post = await fetchOnePost(postId);
return { props: { post } };
}

App目录实现方案

方案1:服务器组件直接获取params(推荐)

在app/posts/[postId]/page.js中,Page组件默认是服务器组件,会自动接收params参数,其中包含路由动态段postId,完全替代原context.query.postId的作用:

// app/posts/[postId]/page.js
async function fetchOnePost(postId) {
  // 替换为你的实际数据请求逻辑
  const res = await fetch(`https://your-api-domain/posts/${postId}`);
  if (!res.ok) throw new Error('Failed to fetch post');
  return res.json();
}

export default async function Page({ params }) {
  const { postId } = params;
  const post = await fetchOnePost(postId);

  return (
    <article>
      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  );
}

方案2:客户端组件获取参数

如果页面是客户端组件(需添加'use client'指令),使用useParams钩子获取路由参数:

// app/posts/[postId]/page.js
'use client';

import { useParams } from 'next/navigation';
import { useState, useEffect } from 'react';

async function fetchOnePost(postId) {
  const res = await fetch(`https://your-api-domain/posts/${postId}`);
  if (!res.ok) throw new Error('Failed to fetch post');
  return res.json();
}

export default function Page() {
  const { postId } = useParams();
  const [post, setPost] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const getPost = async () => {
      try {
        const data = await fetchOnePost(postId);
        setPost(data);
      } catch (err) {
        console.error(err);
      } finally {
        setIsLoading(false);
      }
    };

    getPost();
  }, [postId]);

  if (isLoading) return <div>Loading...</div>;
  if (!post) return <div>Post not found</div>;

  return (
    <article>
      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  );
}

核心说明

  • 服务器组件中,params对象完全等效于原getServerSideProps的context.query,动态路由段会自动映射到params的对应属性。
  • 客户端组件必须通过useParams钩子获取路由参数,且需声明'use client'。
  • 无论哪种场景,都建议通过参数传递postId给fetchOnePost,保持函数的独立性和可测试性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:52:38