Next.js 14 Server Actions 完全攻略:新手也能輕鬆上手的神奇功能!

嘿嘿,各位親愛的開發者朋友們!今天要跟大家分享的是 Next.js 14 中一個超級炫酷的新功能 - Server Actions。這個功能簡直就像是給我們的程式碼打了雞血一樣,讓整個開發過程變得更加順暢和有趣!不管你是 Next.js 的老手還是新手,相信看完這篇文章後,你都會對 Server Actions 愛不釋手。那麼,讓我們一起來探索這個神奇的世界吧!

目錄

Server Actions 是啥?別擔心,讓我來解釋給你聽!

首先,我們來聊聊 Server Actions 到底是個什麼東東。簡單來說,Server Actions 就是讓你可以在 Server Components 中定義和使用的一些函式。這些函式可以直接在伺服器端執行,而不需要通過 API 路由。聽起來很厲害對吧?沒錯,它就是這麼厲害!

想像一下,你可以直接在組件中寫一個函式,然後這個函式就可以在伺服器上執行各種操作,比如查詢資料庫、處理檔案等等。這簡直就像是給了我們一個神奇的遙控器,可以隨時隨地操控伺服器!

Server Actions 的核心理念是將伺服器端的邏輯直接整合到 React 組件中,這樣可以大大簡化我們的開發流程。不再需要分別開發前端和後端,然後再想辦法將它們連接起來。現在,你可以在同一個檔案中處理用戶界面和伺服器邏輯,是不是很方便?

Server Actions 有什麼厲害之處?

說到這裡,你可能會問:“這聽起來很酷,但是它到底有什麼用呢?“別急,讓我們來看看 Server Actions 的主要用途和優點:

  1. 簡化程式碼結構: 不需要再為了一個小小的伺服器操作就寫一大堆 API 路由了。整個程式碼結構變得更加清晰明瞭。你可以直接在需要的地方定義和使用 Server Actions,而不用在不同的檔案之間跳來跳去。

  2. 提高效能: 因為是直接在伺服器執行,所以可以減少客戶端和伺服器之間的往返次數,讓你的應用程式跑得飛快!特別是對於需要頻繁與伺服器通信的應用,這種優化可以大大提升用戶體驗。

  3. 增強安全性: 敏感操作可以直接在伺服器端完成,不用擔心被人偷看到或竄改。比如,你可以在 Server Action 中處理身份驗證、授權等敏感操作,而不用將這些邏輯暴露在客戶端。

  4. 無縫整合: 可以完美地與 React 的表單和事件處理機制整合,讓你的開發過程更加順暢。你可以直接在表單的 onSubmit 事件中調用 Server Action,就像調用普通的 JavaScript 函式一樣簡單。

  5. 即時更新: 配合 Next.js 的其他功能,可以實現資料的即時更新,讓你的應用程式更加動態和互動。例如,你可以在 Server Action 中更新資料庫,然後立即更新頁面上的內容,而不需要刷新整個頁面。

  6. 型別安全: 使用 TypeScript 的開發者會特別喜歡這一點。Server Actions 可以與 TypeScript 完美配合,讓你在編寫伺服器端邏輯時也能享受到強型別的好處。

  7. 更好的錯誤處理: Server Actions 提供了更直接的錯誤處理機制。你可以直接在 action 中捕獲和處理錯誤,然後將結果返回給客戶端,而不需要處理複雜的 HTTP 狀態碼和錯誤訊息。

  8. 降低學習成本: 對於前端開發者來說,Server Actions 降低了學習後端技術的門檻。你可以使用熟悉的 JavaScript/TypeScript 語法來編寫伺服器端邏輯,不需要學習新的語言或框架。

怎麼使用 Server Actions?跟著我的步驟走就對了!

好了,說了這麼多,你一定迫不及待想要試試看了吧?別擔心,我這就手把手教你怎麼使用 Server Actions!

步驟 1: 建立 Server Action

首先,我們需要建立一個 Server Action。在你的 Next.js 專案中,創建一個新的檔案,比如叫做 actions.js。然後,在檔案的最上方加上 'use server' 指令,這樣整個檔案中的函式都會被視為 Server Actions。

'use server'

export async function createPost(content) {
  // 這裡可以進行資料庫操作、檔案處理等伺服器端的工作
  console.log('Creating new post:', content);
  // 假設我們將新文章保存到資料庫
  const newPost = await db.posts.create({ content });
  return { success: true, post: newPost };
}

在這個例子中,我們定義了一個 createPost 函式,它接受一個 content 參數,然後將這個內容保存到資料庫中。注意,這個函式是非同步的,因為大多數伺服器端操作都是非同步的。

步驟 2: 在組件中使用 Server Action

接下來,我們可以在任何 Client Component 中使用這個 Server Action。例如,我們可以創建一個表單來新增文章:

'use client'

import { createPost } from './actions'

export default function NewPostForm() {
  async function handleSubmit(event) {
    event.preventDefault()
    const content = event.target.content.value
    const result = await createPost(content)
    if (result.success) {
      console.log('New post created:', result.post)
      // 可以在這裡更新 UI 或進行其他操作
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <textarea name="content" required />
      <button type="submit">發佈文章</button>
    </form>
  )
}

就是這麼簡單!現在,當用戶提交表單時,createPost Server Action 就會在伺服器端執行,處理新文章的創建工作。

注意,我們在組件頂部加了 'use client' 指令,這是因為我們需要使用 React 的事件處理機制。Server Actions 可以在 Client Components 中調用,但不能在其中定義。

進階技巧:使用 next-safe-action 讓你的 Server Actions 更上一層樓!

如果你想要讓你的 Server Actions 變得更加強大和安全,我強烈推薦你使用 next-safe-action 這個套件。它能夠幫助你更好地處理錯誤、驗證輸入,並提供更好的型別安全性。

來看看怎麼使用它:

  1. 首先,安裝套件:
npm install next-safe-action
  1. 然後,修改我們的 Server Action:
import { createSafeAction } from 'next-safe-action'
import { z } from 'zod'

const createPostSchema = z.object({
  content: z.string().min(1).max(1000)
})

export const createSafePost = createSafeAction(createPostSchema, async ({ content }) => {
  // 這裡是我們的 Server Action 邏輯
  console.log('Creating new post:', content)
  const newPost = await db.posts.create({ content })
  return { success: true, post: newPost }
})
  1. 最後,在組件中使用:
'use client'

import { useAction } from 'next-safe-action/hook'
import { createSafePost } from './actions'

export default function NewPostForm() {
  const { execute, result, status } = useAction(createSafePost)

  async function handleSubmit(event) {
    event.preventDefault()
    const content = event.target.content.value
    await execute({ content })
  }

  return (
    <form onSubmit={handleSubmit}>
      <textarea name="content" required />
      <button type="submit" disabled={status === 'executing'}>
        {status === 'executing' ? '發佈中...' : '發佈文章'}
      </button>
      {result?.data && <p>文章發佈成功!</p>}
      {result?.error && <p>發生錯誤: {result.error.message}</p>}
    </form>
  )
}

看到了嗎?使用 next-safe-action,我們可以輕鬆處理執行狀態、錯誤和成功情況,讓整個過程變得更加順暢和安全。

Server Actions vs. 傳統 MVC 架構:誰更勝一籌?

在我們深入了解 Server Actions 的優點之前,讓我們先來看看它與傳統 MVC (Model-View-Controller) 架構有什麼不同。這個比較會讓你更清楚地了解為什麼 Server Actions 在現代 Web 開發中如此受歡迎。

MVC 架構:老當益壯的經典模式

MVC 架構已經存在很長時間了,它將應用程式分為三個主要部分:

  1. Model (模型): 負責數據和業務邏輯
  2. View (視圖): 負責呈現用戶界面
  3. Controller (控制器): 負責處理用戶輸入並協調 Model 和 View

在傳統的 Web 應用中,這通常意味著:

  • 後端處理 Model 和 Controller
  • 前端負責 View
  • 通過 API 進行前後端通信

Server Actions:新世代的全端整合方案

相比之下,Server Actions 採用了一種更加整合的方法:

  1. 模型: 仍然存在於伺服器端
  2. 視圖: 使用 React 組件 (可以是 Server 或 Client 組件)
  3. 控制器: 直接整合在 Server Components 或 Server Actions 中

讓我們來看看這兩種方法的對比:

特點傳統 MVCServer Actions
代碼組織嚴格分離前後端前後端代碼可以緊密集成
數據流通過 API 請求直接在伺服器執行,減少往返
開發效率需要分別開發前後端可以在同一個文件中處理前後端邏輯
學習曲線相對簡單,概念清晰需要理解 React 和 Next.js 的新概念
性能可能需要多次 API 調用可以減少 API 調用,提高性能
安全性需要在 API 層處理安全問題敏感操作直接在伺服器執行,更安全

當然,讓我們繼續深入探討 Server Actions 和傳統 MVC 架構的比較,以及更多關於 Server Actions 的實際應用和最佳實踐。

哪個更好?這要看情況啦!

老實說,沒有一個架構是完美的,選擇哪一個要根據你的項目需求來決定。

如果你正在開發一個需要前後端完全分離的大型應用,或者你的團隊已經非常熟悉 MVC 模式,那麼傳統的 MVC 架構可能更適合你。

但是,如果你想要:

  • 更快的開發速度
  • 更好的性能
  • 更緊密的前後端整合
  • 更簡單的部署流程

那麼 Server Actions 絕對值得你嘗試!

實際例子:讓我們看看差異

為了讓你更直觀地理解這兩種方法的差異,我們來看一個簡單的「新增文章」功能的實現:

傳統 MVC 方式:

  1. Model (後端,例如 Node.js + Express):
// models/post.js
const db = require('../database');

class Post {
  static async create(content) {
    return db.posts.create({ content });
  }
}

module.exports = Post;
  1. Controller (後端):
// controllers/postController.js
const Post = require('../models/post');

exports.createPost = async (req, res) => {
  try {
    const post = await Post.create(req.body.content);
    res.json({ success: true, post });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};
  1. View (前端,React):
// NewPostForm.jsx
import React, { useState } from 'react';
import axios from 'axios';

export default function NewPostForm() {
  const [content, setContent] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await axios.post('/api/posts', { content });
      console.log('New post created:', response.data.post);
      setContent('');
    } catch (error) {
      console.error('Error creating post:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <textarea 
        value={content} 
        onChange={(e) => setContent(e.target.value)} 
        required 
      />
      <button type="submit">發佈文章</button>
    </form>
  );
}

使用 Server Actions 的方式:

// NewPostForm.jsx
'use client'

import { createPost } from './actions'

export default function NewPostForm() {
  async function handleSubmit(event) {
    event.preventDefault()
    const content = event.target.content.value
    const result = await createPost(content)
    if (result.success) {
      console.log('New post created:', result.post)
      event.target.reset()
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <textarea name="content" required />
      <button type="submit">發佈文章</button>
    </form>
  )
}
// actions.js
'use server'

import { db } from './database'

export async function createPost(content) {
  try {
    const newPost = await db.posts.create({ content })
    return { success: true, post: newPost }
  } catch (error) {
    return { success: false, error: error.message }
  }
}

看到差異了嗎?使用 Server Actions,我們將原本分散在前後端的邏輯整合在了一起,大大簡化了代碼結構和開發流程。這不僅讓代碼更容易維護,也提高了開發效率。

Server Actions 的最佳實踐

在使用 Server Actions 時,有一些最佳實踐可以幫助你更好地組織代碼和提高應用性能:

  1. 適度使用: 雖然 Server Actions 很強大,但並不是所有操作都需要用它。對

於簡單的客戶端狀態管理,仍然可以使用 React 的 state 和 hooks。

  1. 錯誤處理: 在 Server Action 中要做好錯誤處理,並將錯誤信息返回給客戶端。這樣可以在 UI 中顯示適當的錯誤信息。

  2. 輸入驗證: 在 Server Action 中驗證輸入數據,以確保數據的完整性和安全性。可以使用像 Zod 這樣的庫來進行驗證。

  3. 使用 TypeScript: 利用 TypeScript 的類型系統,可以在編譯時捕獲潛在的錯誤,提高代碼質量。

  4. 優化性能: 對於耗時的操作,考慮使用緩存或後台作業來提高性能。

  5. 保持 Server Actions 的純粹性: 盡量讓 Server Actions 保持純粹,只處理數據操作,不要在其中包含太多的業務邏輯。

  6. 合理組織代碼: 將相關的 Server Actions 組織在一起,可以按照功能或者模塊來組織。

  7. 安全性考慮: 對於敏感操作,確保在 Server Action 中進行適當的權限檢查。

常見問題解答

  1. Q: Server Actions 可以完全替代 API 路由嗎? A: 雖然 Server Actions 可以處理很多原本需要 API 路由的場景,但它們並不能完全替代 API 路由。API 路由仍然適用於需要對外提供 API 的場景,或者需要更複雜的 HTTP 操作的情況。

  2. Q: Server Actions 對 SEO 有影響嗎? A: Server Actions 本身不會直接影響 SEO,因為它們主要用於處理用戶交互。但是,通過減少客戶端渲染的需求,它可以間接提高頁面的加載速度,這可能對 SEO 有正面影響。

  3. Q: 如何處理 Server Actions 中的身份驗證? A: 你可以在 Server Actions 中訪問伺服器端的 session 或者其他身份驗證機制。Next.js 提供了 getServerSession 函數,可以在 Server Actions 中使用它來獲取用戶的 session 信息。

  4. Q: Server Actions 可以在 getServerSideProps 中使用嗎? A: 不可以。Server Actions 主要用於處理客戶端發起的操作,而 getServerSideProps 是在頁面加載時在伺服器端運行的。這兩者的使用場景不同。

  5. Q: 如何測試 Server Actions? A: 你可以使用 Jest 等測試框架來單元測試 Server Actions。對於集成測試,可以使用 Cypress 或 Playwright 等工具來模擬用戶交互並測試整個流程。

總結:Server Actions 是你的新好朋友!

好啦,講了這麼多,相信你已經對 Next.js 14 的 Server Actions 有了一個全面的了解。讓我們來做個簡單的總結:

特點描述
簡化開發不需要寫額外的 API 路由
提升效能減少客戶端和伺服器的往返
增強安全性敏感操作直接在伺服器執行
易於使用與 React 表單無縫整合
彈性強大可以處理各種伺服器端任務

Server Actions 真的是一個超級強大的功能,它讓我們的開發過程變得更加簡單、高效和安全。不管你是在開發一個小型的個人專案,還是大型的企業應用,Server Actions 都能夠為你帶來很大的幫助。

它不僅簡化了我們的代碼結構,還提高了應用的性能和安全性。通過將前後端邏輯緊密整合,Server Actions 為我們提供了一種更加直觀和高效的開發方式。

當然,像所有新技術一樣,Server Actions 也有其適用的場景和限制。它並不能完全替代傳統的 MVC 架構或 API 路由,但在許多情況下,它確實提供了一種更優雅的解決方案。

最重要的是,Server Actions 體現了 Next.js 和 React 生態系統不斷創新的精神。它為我們提供了新的工具來構建更好的 Web 應用,同時保持了 React 的簡潔和直觀。

所以,親愛的開發者朋友們,還在等什麼呢?趕快打開你的 IDE,開始嘗試 Server Actions 吧!相信我,當你真正用起來的時候,你會發現它就像是程式設計界的魔法棒,讓一切變得如此簡單和美好。

記住,技術的進步永無止境,保持學習和嘗試新事物的熱情,你就能在這個快速發展的 Web 開發世界中始終保持領先。希望這篇文章能夠幫助你更好地理解和使用 Server Actions,為你的下一個項目帶來更多可能性!

祝大家開發愉快,下次見啦!