Next.js App Router 頁面開發提示詞(服務端組件與客戶端組件怎麼分、Server Actions 表單、緩存與加載狀態)

用 Next.js App Router 做頁面時,搞不清哪些組件該放服務端、哪些要加 use client、數據在哪裏取、表單怎麼提交時用:描述頁面功能,AI 給出組件劃分方案、數據獲取與緩存策略、Server Action 表單處理、加載與錯誤狀態,以及常見的坑。

NNathaniel bigo··原創首發·AI 輔助撰寫
通用大模型 對話模型通用
你是一名熟悉 Next.js App Router 的全棧工程師。請幫我實現下面的頁面。

- Next.js 版本:[如 15 或 16]
- 頁面路由與功能:[頁面路由與功能](例:/orders 訂單列表,支持篩選、分頁、取消訂單)
- 數據來源:[數據來源](例:直接查數據庫 Prisma、調用內部 REST 接口)
- 是否需要登入與權限:[鑑權方式]
- 交互需求:[如篩選條件實時生效、取消後列表自動刷新]
- 對 SEO 和首屏速度的要求:[高/一般]

請輸出:
1. 組件劃分:畫出組件樹,標明每個組件是服務端組件還是客戶端組件,以及理由。原則:預設服務端組件;只有需要狀態、事件處理、瀏覽器接口的部分才是客戶端組件,並且把客戶端邊界盡量往葉子節點推。
2. 數據獲取:在服務端組件中如何取數;篩選與分頁參數通過地址列查詢參數傳遞;說明這些數據請求在當前版本中的緩存行為與重新驗證方式(需要實時的數據怎麼處理)。
3. 數據修改:用 Server Action 實現「取消訂單」:
   - 在 Action 內部重新校驗登入狀態和權限(不能信任來自客戶端的參數);
   - 用模式校驗輸入;
   - 修改後讓相關頁面數據重新驗證;
   - 表單提交中的加載狀態和錯誤提示。
4. 加載與錯誤:用約定文件實現加載骨架和錯誤邊界;找不到數據時返回 404 頁面。
5. 元數據:用 generateMetadata 生成頁面標題與描述;動態路由的 notFound 處理。
6. 常見錯誤檢查:在服務端組件中使用了 hooks、把不可序列化的值(函數、類實例)作為屬性從服務端組件傳給客戶端組件、在客戶端組件中引入了只能在服務端用的模組(數據庫客戶端、密鑰)。

Next.js 各版本之間緩存預設值、部分 API 是否異步等行為有變化,凡是與版本相關的寫法,註明「以你所用版本的官方文檔為準」。

高亮處換成你自己的內容:[如 15 或 16]、[頁面路由與功能]、[數據來源]、[鑑權方式]、[如篩選條件實時生效、取消後列表自動刷新]、[高/一般]

ChatGPT Plus 充值

已被複製 0 次

使用說明

怎麼填變量:[Next.js 版本] 一定要寫準確。App Router 在幾個大版本之間改過緩存預設值,路由參數也從普通對象改成了需要等待的異步值,照着舊教學寫很容易出錯。[數據來源] 如果是直接查數據庫,所有查詢代碼都必須只在服務端運行。

常見坑:

  • 在頁面最外層加上 use client,整個頁面都變成客戶端渲染,失去了服務端組件的好處。只在真正需要交互的小組件上加。
  • 以為 Server Action 是「內部函數」就不做權限校驗。它本質上是一個可以被直接調用的接口,必須在內部重新檢查用戶身份和參數。
  • 修改數據後頁面沒有刷新,通常是忘了讓對應路徑或標籤的數據重新驗證。

追問技巧:追問「把篩選條件改成可分享的連結,刷新頁面後條件保持不變」,或「這個頁面在哪些情況下會被靜態生成、哪些情況下是動態渲染,怎麼確認」。

示例輸出

示例,僅供參考(組件樹節選)
app/orders/page.tsx            服務端組件:讀取查詢參數,查詢訂單列表
├─ OrderFilters.tsx            客戶端組件:下拉框改變時更新地址列查詢參數
├─ OrderTable.tsx              服務端組件:渲染表格
│  └─ CancelButton.tsx         客戶端組件:調用 Server Action,顯示提交中狀態
└─ Pagination.tsx              服務端組件:用連結切換頁碼
app/orders/loading.tsx         加載骨架
app/orders/actions.ts          Server Action:cancelOrder
ts
// app/orders/actions.ts
'use server'
import { revalidatePath } from 'next/cache'
import { z } from 'zod'

export async function cancelOrder(formData: FormData) {
  const user = await requireUser()                        // 重新校驗登入
  const { orderId } = z.object({ orderId: z.coerce.number().int() }).parse({ orderId: formData.get('orderId') })
  const order = await db.order.findUnique({ where: { id: orderId } })
  if (!order || order.userId !== user.id) return { error: '訂單不存在' }   // 防越權
  if (order.status !== 'PENDING') return { error: '當前狀態不能取消' }
  await db.order.update({ where: { id: orderId }, data: { status: 'CANCELLED' } })
  revalidatePath('/orders')
  return { ok: true }
}

同款作品

用這條提示詞做出來的作品;原作者會因此獲得積分

做同款

還沒有同款,來做第一個。

Nathaniel 的更多內容

同主題

同模型

0 條評論

登入 後參與評論

還沒有評論,來搶沙發~