2026年6月22日 星期一

為什麼在寫Next.js route中,參數要寫做「{params}....」而不是直接寫做params,背後是有什麼機制?

 如果你有在寫Next.js的api route.ts的話,會常看到類似以下的片段
------------

export async function GET(

  req: Request,

  {params}: { params: Promise<{ batchId: string }> }

) {

  const { batchId } = await params
...
....
...

}

------------
為什麼是寫作「{params}」而非是「params」就好?
事實上,那是簡寫,真正的code是
----
export async function GET(
  req: Request,
  context: { params: Promise<{ batchId: string }> }
) {
  const { batchId } = await context.params
...
...
}

----
那問題來了,context是什麼,route到底會收到什麼參數?
routing從url的path解析出[...]/[...]/ 對應到相對的route.ts及方法後(以GET為例),參數內容如下
-------------
GET(req, context)
  │         │
  │         └── Route context (URL structure)
  │               context.params  → path segments [batchId],
          
                                               [sessionId]
  │               context.searchParams →
  │               query string (?tab=x) [page routes only]
  │
  └── Request object (HTTP request details)
req.method   → GET / POST / DELETE
req.headers  → Authorization, Content-Type, cookies...
req.body     → POST/PUT body (JSON payload)
req.url      → full URL string
-------------
就是這樣的內容,AI會直接把context......寫成{params} 的簡寫方式
A:「那,如果後面帶『?key=value』的方式如何取值?」
Q:就要從req.url轉換出「searchParams」了
--------------
  const { searchParams } = new URL(req.url);

  // Example:
  // /api/user?id=1&name=john&role=admin
  const id = searchParams.get("id");
  const name = searchParams.get("name");
  const role = searchParams.get("role");

上述是在route.ts裡的寫法

而在tsx裡的寫法卻又是不一樣了

-----如同之前context.searchParams → query string (?tab=x) [page routes only]所示-------
// Page components (page.tsx) ONLY:
export default function Page({
  params,
  searchParams,  // ← available here as context prop
}: {
  params: Promise<{ batchId: string }>
  searchParams: Promise<{ tab: string }>
}) {
  const { batchId } = use(params)
  const { tab } = use(searchParams)  // ← works in page.tsx
   ...
   .....
   ...
}
------------
 ts & tsx 寫法不同,千萬要注意
(好像對AI generated code如此講究的工程師也不多了吧.現在都是直接測了能跑交件了)