iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
Modern Web

前進React 生態系 : 技術應用與概念解析系列 第 18

Day 18 - 掌握 Server Functions、Client 和 Server Components 的互動技巧

  • 分享至 

  • xImage
  •  

Server Component 和 Client Component 的互動

在昨天有介紹到 Server Components 是沒有辦法互動的,這時候就需要搭配 Client Component 來互動了。要在 Client Component 使用 Server Component,Server Component 必須用 children props 的方式傳入。

使用範例:

import ClientComponent from "./client-component";
import ServerComponent from "./server-component";

export default function App() {
  return (
    <ClientComponent>
      <ServerComponent />
    </ClientComponent>
  );
}

"use client"

當有使用 React Server Component 或相容的 library 時,才需要使用到 "use client"

"use client" 用來標記在 client 端運行的程式碼,使用方式是必須放在檔案的最開頭, 在 import 的內容和其他程式碼上方。

"use client" 指令可以當作 client 和 server 的邊界。這個邊界是根據模組依賴關係樹 (module dependency tree)來建立,而不是依據渲染樹(render tree)。

  • Client Components 是在渲染樹中在 Client 端 render 的元件。
  • Server Components 是在渲染樹中在 Server 端 render 的元件。

所以即使某個元件在結構上具有父子關係,也並不代表它們會在相同的渲染環境中運行。
另外在 Client Components render 之前,Server Components 就已經 render 完成。

圖片說明:

說明圖片

在預設情況下,元件會被當作 Server Components。如果元件有使用 "use client" 指令在模組中定義的,或者元件是在 Client Component 中被 import 的,都會被當作 Client Components。

在上方的範例中,AppFancyTextCopyright 都是 Server Components,而 InspirationGenerator 和底下被 import 的元件會是 Client Components。

所以一個 Component 可以是 Server Components,也可以是 Client Components。某個元件是否為 Client Component,取決於被使用方式。像 FancyText 就是一個例子。

要注意的是這邊的 Server Components 僅限於沒有使用 server 功能的元件(不需要等待資料的),如果是 Async Components 的話直接 import 到 Client Component 中會出現錯誤,必須用 children props 的方式傳入。

Server Components 和 props

當我們在 Client Components 中使用 Server Components 時,透過 props 可以將資料從父元件傳遞到子元件。但因為 Server Components 和 Client Components 是在不同的環境中渲染,傳遞 props 會有一些限制。傳遞的 props 必須是 可序列化的 (serializable) 或 React Components,才能成功傳遞到 Client Component。

可序列化的 props 包括:Primitives(如 string、number)、可序列化的物件(如 Array、Map、Set)、日期(Date)、Client 或 Server Component 的元素(JSX)、Server Actions 的函式、Promise 等。

更多詳細內容可以參考 React 文件

"use server" 和 Server Functions

另一個相似的指令是 "use server" ,不過 "use server" 不是用在 Server Component 中,而是用在 Server Functions。

一樣是當有使用 React Server Component 或相容的 library 時,才需要使用到 "use server"

Server Functions 簡介

透過 Server Functions (之前叫 Server Actions),可以在 Client 端執行某些操作時,將請求發送到 Server 端進行處理,通常是用於與資料庫、API 等後端服務互動。而 "use server" 用來標記可以從 Client 端調用的 server-side function。另外使用 "use server" 標記的函式必須是非同步的(async),因為 Server Actions 的底層實現是依賴於非同步網路請求。

Server Functions 使用範例

"use server" 只能在 Server 端的檔案中使用,不能在 Client 端的程式碼中使用。使用方式有兩種,一種是在 Server Component 中建立,另一種直接建立在獨立的檔案中。

  1. 在 Server Component 中定義: "use server" 必須放在 async function 的最上方。
import Button from "./Button";

function EmptyNote() {
  async function createNoteAction() {
    "use server";

    await db.notes.create();
  }

  return <Button onClick={createNoteAction} />;
}
  1. 在獨立的檔案中定義: "use server" 必須放在檔案的最上方,位於 import 和其他程式碼上方
"use server";

export async function create() {
  // 調用 database 或其他 server-side 相關邏輯
}

其他更多 Server Functions 相關的內容,會在明天的文章說明。

參考資料:

https://react.dev/reference/rsc/server-components#adding-interactivity-to-server-components
https://react.dev/reference/rsc/use-client#building-with-interactivity-and-state
https://react.dev/reference/rsc/server-action
https://react.dev/reference/rsc/use-server
https://ithelp.ithome.com.tw/articles/10317180


上一篇
Day 17 - React Server Components 簡介
下一篇
Day 19 - Server Functions、action prop 與新的 Hooks
系列文
前進React 生態系 : 技術應用與概念解析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言