React 19 Server Functions 完整教學:RPC 模式讓前後端界線消失的魔法
第一次看到 React 19 的 Server Functions 時,我的反應是:「等等,這不就是 PHP 嗎?」前端可以直接呼叫伺服器函式,不用寫 API endpoint,不用管序列化,聽起來有點像開倒車。但深入研究後我發現,這背後的 RPC 模式其實是近年來前端架構中最聰明的設計之一。
什麼是 Server Functions
Server Functions 是用 "use server" 指令標記的函式,它們只在伺服器端執行,但可以從 Client Component 中呼叫,就好像是本地函式一樣。React 19 中 Server Functions 已經是穩定功能,不會在 minor version 之間有破壞性變更。
// actions.ts
"use server"
export async function createUser(formData: FormData) {
const name = formData.get("name") as string
const email = formData.get("email") as string
// 這段程式碼只在伺服器上執行
const user = await db.users.create({ name, email })
return user
}當這個函式從 Client Component 被呼叫時,React 框架會自動把它轉換成一個網路請求——你寫的是函式呼叫,實際執行的是一個 HTTP POST。這就是 RPC(Remote Procedure Call)模式。
RPC 模式運作原理
RPC 模式的核心概念很簡單:讓遠端呼叫看起來像本地呼叫。在 React 19 Server Functions 的脈絡中,運作方式是:
- 編譯時期:打包工具(Webpack/Turbopack)找到所有
"use server"標記的函式 - 程式碼分離:伺服器端程式碼從 client bundle 中移除,替換成一個 RPC stub
- 客戶端呼叫:當 Client Component 呼叫這個函式時,stub 發送一個 fetch 請求到伺服器
- 伺服器執行:伺服器收到請求,執行原始函式,回傳結果
- 自動序列化:React 自動處理參數和回傳值的序列化/反序列化
整個過程對開發者來說是透明的——你寫的就是普通的函式呼叫,剩下的都由框架處理。
use server 指令實戰
Server Functions 可以在兩個地方宣告:
1. 獨立檔案(推薦)
// app/actions.ts
"use server"
export async function submitFeedback(text: string) {
await db.feedback.create({ text, createdAt: new Date() })
revalidatePath("/feedback")
}2. Server Component 內部
// app/page.tsx (Server Component)
export default function Page() {
async function handleSubmit(formData: FormData) {
"use server"
// 伺服器端邏輯
}
return <form action={handleSubmit}>...</form>
}我個人偏好把 Server Functions 集中在獨立檔案中管理。理由很簡單:當你的 app 長大之後,散落在各 component 中的 "use server" 函式很難追蹤,而且不容易重用。
延伸閱讀:如果你在用 Next.js 開發,搭配 Next.js PPR 部分預渲染教學 一起看效果更好。
搭配 Form Actions 使用
Server Functions 最自然的使用場景是 Form Actions。React 19 讓你可以直接把 Server Function 傳給 form 的 action 屬性:
"use client"
import { submitFeedback } from "./actions"
import { useActionState } from "react"
export function FeedbackForm() {
const [state, action, isPending] = useActionState(
submitFeedback,
null
)
return (
<form action={action}>
<textarea name="text" required />
<button disabled={isPending}>
{isPending ? "送出中..." : "送出回饋"}
</button>
{state?.error && <p>{state.error}</p>}
</form>
)
}搭配 useActionState(React 19 新 hook),你可以優雅地處理 loading 狀態和錯誤。不需要自己管理 useState、useEffect、fetch 那一堆 boilerplate。
TanStack Start 的 Server Functions
除了 Next.js,TanStack Start 也提供了自己的 Server Functions 實作。它的 RPC 系統提供了:建構時程式碼分離、型別安全的通訊、自動序列化、與路由的深度整合。
TanStack Start 的做法跟 React 官方類似,但更強調型別安全。在 TanStack 中,server function 的輸入和輸出都是完整 TypeScript 型別化的,你在 client 端呼叫時可以得到完整的 IntelliSense 支援。
如果你正在評估框架選項,React 19.2 深度解析也值得參考,了解最新的效能追蹤和快取功能。
安全性考量與最佳實踐
Server Functions 本質上是公開的 HTTP endpoint。任何人都可以直接發 POST 請求到你的 Server Function endpoint,繞過前端的驗證邏輯。所以你必須在 Server Function 內部做完整的輸入驗證和授權檢查。
值得注意的安全事件:2025 年底發生了一系列 React Server Components 的安全漏洞,包括一個 CVSS 10.0 的 RCE 漏洞(CVE-2025-55182)。React 19.0.2+ 和 Next.js 15.1.4+ 已經修復了所有問題。確保你的版本是最新的。
最佳實踐清單:
- 在每個 Server Function 開頭驗證身份和權限
- 使用 Zod 或類似工具驗證所有輸入
- 不要在 Server Function 中暴露敏感的內部資訊
- 加上 rate limiting(如果框架沒有內建的話)
- 保持 React 和框架版本更新
從 API Routes 遷移指南
如果你現在的專案是用 API Routes(像是 Next.js 的 /api/* 路由)來處理前後端溝通,遷移到 Server Functions 的步驟大概是這樣:
- 識別哪些 API route 是被前端直接呼叫的(排除第三方 webhook 等)
- 把 API route 的邏輯提取到
"use server"函式中 - 把前端的 fetch 呼叫替換成直接呼叫 Server Function
- 加上適當的錯誤處理和型別
- 移除不再需要的 API route 檔案
注意:不是所有 API route 都適合轉換。如果你的 endpoint 需要被第三方系統呼叫(webhook、mobile app 等),它就應該繼續是 API route。Server Functions 只適合「前端直接呼叫伺服器」的場景。
結語
React 19 的 Server Functions 透過 RPC 模式,真正實現了「前後端邊界消失」的開發體驗。你不再需要為了一個簡單的資料庫操作而建立 API endpoint、寫 fetch 請求、處理序列化——直接呼叫函式就好。這不是開倒車回到 PHP 時代,而是站在現代工具鏈的肩膀上,把「前後端溝通」這個重複且無聊的工作自動化了。建議從一個小功能開始遷移,體驗這種新的開發範式帶來的效率提升。
繼續閱讀
Zustand vs Redux 2026 比較:React 狀態管理輕量方案到底該選誰?
深入比較 2026 年 Zustand 與 Redux 在 React 狀態管理上的差異,透過實際程式碼展示兩者的寫法差異,分析 Zustand Slice Pattern、Middleware 生態系與效能優勢,幫助開發者做出最佳選擇。
相關文章
你可能也喜歡
探索其他領域的精選好文