Next.js 13.4新App Router中如何获取查询参数?
解决方案:Next.js 13.4 App Router 获取查询参数问题
核心问题分析
- 你使用的
useRouter来自next/router,这是Pages Router专属API,在App Router中完全不兼容。 - 原
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拉取完整数据:
- 简化Link写法:
<Link href={`/product/${item._id}`}> <button>详情</button> </Link>
- 详情页获取数据:
// 服务器组件示例 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
相关产品推荐
相关产品推荐

