Next.js中如何将动态路由参数传递给API路由
在Next.js中传递动态路由id到API路由的实现方案
1. 先实现接收id的API路由
根据你使用的是App Router还是Pages Router,API路由的写法略有不同:
App Router(Next.js 13+)
在app/api/books/[id]/route.js中创建路由:
export async function GET(request, { params }) { // 从路由参数中获取id const { id } = params; // 这里替换成你的数据获取逻辑(比如数据库查询) const bookData = await getBookFromDatabase(id); return Response.json(bookData); } // 示例数据获取函数,根据实际情况替换 async function getBookFromDatabase(id) { // 模拟数据库查询逻辑 return { id, title: `Book ${id}`, description: `Details of book ${id}` }; }
Pages Router
在pages/api/books/[id].js中创建路由:
export default async function handler(req, res) { // 从query中获取id const { id } = req.query; const bookData = await getBookFromDatabase(id); res.status(200).json(bookData); } async function getBookFromDatabase(id) { return { id, title: `Book ${id}`, description: `Details of book ${id}` }; }
2. 在动态页面组件中获取id并调用API
分两种路由模式给出实现:
App Router - 服务器组件(无需客户端交互)
在app/books/[id]/page.js中:
async function BookPage({ params }) { const { id } = params; // 服务器组件中调用API需使用完整URL,生产环境可替换为实际域名 const res = await fetch(`http://localhost:3000/api/books/${id}`, { // 需实时数据时添加缓存配置 cache: 'no-store' }); if (!res.ok) { throw new Error('Failed to fetch book'); } const book = await res.json(); return ( <div> <h1>{book.title}</h1> <p>{book.description}</p> </div> ); } export default BookPage;
App Router - 客户端组件(需要交互逻辑)
在app/books/[id]/page.js中添加'use client'指令:
'use client'; import { useEffect, useState } from 'react'; import { useParams } from 'next/navigation'; function BookPage() { const params = useParams(); const id = params.id; const [book, setBook] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { async function fetchBook() { if (!id) return; try { // 客户端组件可直接使用相对路径 const res = await fetch(`/api/books/${id}`); if (!res.ok) throw new Error('Book not found'); const data = await res.json(); setBook(data); } catch (err) { setError(err.message); } finally { setLoading(false); } } fetchBook(); }, [id]); if (loading) return <div>Loading book details...</div>; if (error) return <div>Error: {error}</div>; return ( <div> <h1>{book.title}</h1> <p>{book.description}</p> </div> ); } export default BookPage;
Pages Router 页面组件
在pages/books/[id].js中:
import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; function BookPage() { const router = useRouter(); const { id } = router.query; const [book, setBook] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { async function fetchBook() { // 等待路由参数加载完成 if (!id) return; try { const res = await fetch(`/api/books/${id}`); if (!res.ok) throw new Error('Failed to load book'); const data = await res.json(); setBook(data); } catch (err) { setError(err.message); } finally { setLoading(false); } } fetchBook(); }, [id]); if (loading) return <div>Loading...</div>; if (error) return <div>{error}</div>; return ( <div> <h1>{book.title}</h1> <p>{book.description}</p> </div> ); } export default BookPage;
关键注意点
- 服务器组件调用API时需用完整URL,生产环境可通过环境变量配置域名
- 客户端组件可直接使用相对路径调用API
- 需要实时数据时,在fetch请求中添加
cache: 'no-store'(App Router)或配置revalidate: 0(Pages Router)避免缓存
内容的提问来源于stack exchange,提问作者Amr Viernes
相关产品推荐
相关产品推荐

