Next.js页面传动态路由ID后API无法获取ID的问题排查
解决Next.js API路由无法获取动态ID的问题
核心问题分析
你的代码存在两个关键错误:
- API路由结构不匹配:前端请求的是
/api/shop/${id}(动态路径参数),但你的API路由未设置为动态路由,导致无法捕获路径中的id。 - 混用App Router与Pages Router的API写法:在App Router环境下使用
export async function GET的写法,却导入了Pages Router的NextApiRequest/NextApiResponse类型,还错误地用req.query获取路径参数——req.query仅适用于?id=123这类查询参数,无法读取路径中的动态参数。
修复步骤
1. 调整API路由文件结构
创建对应的动态API路由文件,匹配前端请求路径:
app/ └── api/ └── shop/ └── [id]/ └── route.ts # 专门处理动态ID的API路由文件
2. 修正API路由代码
替换route.ts中的代码为以下内容:
import prisma from '@/lib/prisma'; import { NextResponse } from 'next/server'; // App Router动态API路由的GET函数,第二个参数包含路径params export async function GET(_req: Request, { params }: { params: { id: string } }) { try { const { id } = params; if (!id) { return NextResponse.json({ error: 'ID parameter is missing' }, { status: 400 }); } // 将ID转为数字(根据你的Prisma模型类型调整) const shopId = Number(id); if (isNaN(shopId)) { return NextResponse.json({ error: 'Invalid ID format' }, { status: 400 }); } const shop = await prisma.shop.findUnique({ where: { id: shopId, }, }); if (!shop) { return NextResponse.json({ error: 'Shop not found' }, { status: 404 }); } return NextResponse.json({ shop }); } catch (error) { console.error('Error fetching shop by ID:', error); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } }
3. 前端代码优化(可选)
你的前端page.tsx逻辑正确,可添加类型提示提升代码健壮性:
'use client'; // 必须添加,因为使用了useState、useEffect等客户端钩子 import { useState, useEffect } from 'react'; import { useParams } from 'next/navigation'; export default function Shop({ children, sections = [] }) { const [shopData, setShopData] = useState<Shop | null>(null); const params = useParams() as { id: string }; const { id } = params; useEffect(() => { const fetchData = async () => { try { if (id) { const response = await fetch(`/api/shop/${id}`); if (response.ok) { const result = await response.json(); setShopData(result.shop); } else { console.error('Failed to fetch shop:', response.statusText); } } } catch (error) { console.error('Error fetching shop:', error); } }; fetchData(); }, [id]); // 后续渲染逻辑... } // 根据你的实际数据结构定义Shop类型 type Shop = { id: number; // 其他字段示例:name: string; address: string; };
关键说明
- App Router通过
[id]文件夹命名实现动态路由,路径参数会通过GET函数的第二个参数params传递。 - App Router中API路由使用标准
Request类型,而非Pages Router的NextApiRequest,响应直接用NextResponse处理。 - 转换ID为数字时需做
isNaN校验,避免非法字符导致Prisma查询报错。
内容的提问来源于stack exchange,提问作者Sylwester Zabielski
相关产品推荐
相关产品推荐

