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

Next.js 13.4新App Router中如何获取查询参数?

解决方案:Next.js 13.4 App Router 获取查询参数问题

核心问题分析

  1. 你使用的useRouter来自next/router,这是Pages Router专属API,在App Router中完全不兼容。
  2. 原Link组件中的as属性已在App Router的next/link中被移除,该属性会掩盖查询参数,导致实际URL未携带你传递的参数,这是无法获取参数的直接原因。

步骤1:修复products.tsx中的Link组件

删除as属性,确保查询参数能正常出现在URL中:

import Link from 'next/link';

// 示例写法
<Link 
  href={{ 
    pathname: `/product/${item._id}`, 
    query: { 
      _id: item._id, 
      title: item.title, 
      description: item.description, 
      oldPrice: item.oldPrice, 
      price: item.price, 
      brand: item.brand, 
      image: item.image, 
      isNew: item.isNew, 
      category: item.category, 
    }, 
  }}
>
  <button>详情</button>
</Link>

步骤2:在详情页获取参数(两种方式)

方式一:服务器组件(默认推荐,无需客户端标记)

直接通过组件props接收searchParams和动态路由params:

type ProductPageProps = {
  params: { id: string }; // 动态路由的[id]参数
  searchParams: {
    _id?: string;
    title?: string;
    description?: string;
    oldPrice?: string;
    price?: string;
    brand?: string;
    image?: string;
    isNew?: string;
    category?: string;
  };
};

export default function ProductPage({ params, searchParams }: ProductPageProps) {
  return (
    <div>
      <h1>商品详情</h1>
      <p>路由ID: {params.id}</p>
      <p>ID: {searchParams._id}</p>
      <p>标题: {searchParams.title}</p>
      <p>描述: {searchParams.description}</p>
      <p>原价: {searchParams.oldPrice}</p>
      <p>现价: {searchParams.price}</p>
      <p>品牌: {searchParams.brand}</p>
      <p>图片地址: {searchParams.image}</p>
      <p>是否新品: {searchParams.isNew}</p>
      <p>分类: {searchParams.category}</p>
    </div>
  );
}

方式二:客户端组件(需交互时使用)

使用next/navigation提供的useSearchParams和useParams钩子:

'use client';

import { useParams, useSearchParams } from 'next/navigation';

export default function ProductPage() {
  const params = useParams<{ id: string }>();
  const searchParams = useSearchParams();

  // 逐个获取查询参数
  const _id = searchParams.get('_id');
  const title = searchParams.get('title');

  return (
    <div>
      <h1>商品详情</h1>
      <p>路由ID: {params.id}</p>
      <p>ID: {_id}</p>
      <p>标题: {title}</p>
      <p>描述: {searchParams.get('description')}</p>
      <p>原价: {searchParams.get('oldPrice')}</p>
      <p>现价: {searchParams.get('price')}</p>
      <p>品牌: {searchParams.get('brand')}</p>
      <p>图片地址: {searchParams.get('image')}</p>
      <p>是否新品: {searchParams.get('isNew')}</p>
      <p>分类: {searchParams.get('category')}</p>
    </div>
  );
}

额外优化建议

不建议通过查询参数传递大量商品信息,更合理的做法是只传递商品ID,在详情页通过ID从数据库/API拉取完整数据:

  1. 简化Link写法:
<Link href={`/product/${item._id}`}>
  <button>详情</button>
</Link>
  1. 详情页获取数据:
// 服务器组件示例
async function fetchProduct(id: string) {
  const res = await fetch(`https://your-api.com/products/${id}`);
  if (!res.ok) throw new Error('获取商品数据失败');
  return res.json();
}

export default async function ProductPage({ params }: { params: { id: string } }) {
  const product = await fetchProduct(params.id);

  return (
    <div>
      <h1>商品详情</h1>
      <p>ID: {product._id}</p>
      <p>标题: {product.title}</p>
      {/* 渲染其他字段 */}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:04:53