Skip to main content

Command Palette

Search for a command to run...

React官方文件導讀|為什麼我們需要ServerComponent

Updated
2 min readView as Markdown
React官方文件導讀|為什麼我們需要ServerComponent

這已經是 2020 年 12 月 React 官方公佈 RSC (React Server Componet) 時的文章,以前端世界的更新速度來說是很久遠的資料,但可以讓第一次接觸 RSC 的開發者明白為什麼會創造出這項更新。

主要引用內容皆來自於🔗 2020/12/21-Introducing Zero-Bundle-Size React Server Components

並且整理該 Youtube 影片的內容。

https://www.youtube.com/watch?v=TQQPAU21ZUw

React Server Component(RSCs) 增強了React 基礎,讓React 在Data Fetch中解決了API Response 與我們元件非常耦合的問題。

// ⬇️ 因為需要從一隻 API 讀取資料,造成 Response 與元件非常耦合的範例
const stuff = fetchAllTheStuffJustInCase();

return (
  <ArtistDetails details={stuff.details} artistId={artistId}>
    <TopTracks topTracks={stuff.topTracks} artistId={artistId} />
    <Discography discography={stuff.discography} artistId={artistId} />
  </ArtistDetails>
);

理想上,我們希望我們的代碼長這樣:

// 只需要根據知道目前 Page 的 artisId
function ArtistPage({ artistId }) {
  return (
    <ArtistDetails artistId={artistId}>
      <TopTracks artistId={artistId} />
      <Discography artistId={artistId} />
    </ArtistDetails>
  );
}
// 🌟 並且我們在元件中,自行決定我們要獲取什麼數據
function ArtistDetails({ artistId, children }) {
  const details = fetchDetails(artistId);
  // ...
}

function TopTracks({ artistId }) {
  const topTracks = fetchTopTracks(artistId);
  // ...
}

function Discography({ artistId }) {
  const discography = fetchDiscography(artistId);
  // ...
}

在 Facebook 時期,React 透過 Relay +GraphQL 來解決這件事,透過 GraphQL 指定需要的數據,並用 Relay 將這些 fragments 組合再一起,我們可以一次獲得需要的數據,而不會產生 waterfall。

但 GraphQL 必須有一個 GraphQL backend,在小型的應用程式我們很難做到這件事,在大公司也需要後端技術的配合

原本的寫法會造成water-fall,water-fall 問題如此嚴重是因為 client 端與 Server 端之間存在高延遲,因此 React 需要另一個解決方法,當我們把 Parent Component 放在Server 上,就可以與後端有更快的連結,更快的渲染Child Component。


因此有了RSC (React Server Component) ,RSC 只存在 Server ,僅在 Server 執行,永遠不會 shipped 到 client 端。

RSC 無法使用任何互動性(interactive)的語法,例如React Hook,並且Server Component 只能將已經serialize 後的值傳遞給 Client Component,例如一個function,幸運的是JSX 也是serialize 的,我們也能將JSX 傳遞給Client Component。

RSC 與一般傳統SSR 不同,Server Component 不會直接渲染成HTML,而是渲染成一種特殊格式,再重新獲取Server Component Tree 時也能保持Client Side 的狀態。


Recap:

  • Server Component ,因為在伺服器渲染,所以在客戶端不需要下載Server Component 所使用的函示庫,進一步減少bundle size。

  • Server Component 能夠直接訪問後端資源,不代表你需要拋棄API而直接訪問db,你也可以創層一個API Layer,提供開發者能在這之中有權利切換。

  • React IO Libraries:

    • IO 代表input與output ,以下的library 必不是react 官方維護的,但在Server Component 能為我們帶來助力,這三個library 基本代碼都很小,但能將原生的node 包裝成react 能夠緩存的狀態。

    • react-fs: Filesystem

      • 能在RSC 環境下讀取/寫入檔案(類似Node.js 的fs

      • 也能用於讀取Markdown 檔案。

    • react-pg: PostgreSQL

      • 讓RSC 直接與PostgreSQL 連線。(類似Prisma
    • react-fetch: Fetch

      • 包裝Fetch API,優化成RSC 的資料請求方式。
  • Server Component 只下載實際需要的code,以這份code為例,如果今天用戶不是admin的話,能避免用戶下載到EditToolbar 的code。

  • 根據具體的情況來使用 RSC ,當你需要資料做預處理時你可以放在 Server ,需要透過互動快速取得回應的code 放在 client,這之間的切換都在 React 上,你可以共享代碼、共用元件,RSC 提供更有彈性的解法讓開發者做選擇

    • 原文:Server Component let you decide the tradeoff for every concrete use case
  • Server Component 讓開發者思維可以轉為伺服器驅動,讓 Server 預處理資料後拋給Client ,同時將Client 與Server 視作一個樹,因為 Client 的狀態可以不被銷毀,讓RSC 提供更符合現在用戶體驗的UX。

More from this blog

使用 TansTack 的 infinite Queries 與 TanStack Virtual 製作 grid 排列的虛擬滾動讀取

最近遇到一個需求,UI 為 grid 排列的格狀列表,每個物件可以透過 api 分頁得到。 所以初步分析: 需要根據螢幕斷點,渲染一列不同行數的 grid 需要與 api 進行分頁讀取,每次傳送 page, page_size 列表最大值會非常多,預防 dom 太多造成畫面卡頓,需要使用虛擬滾動 因最近專案多有引入 TansTack ,分頁讀取的部分會用 infinite Queri

Nov 15, 20255 min read
使用 TansTack 的 infinite Queries 與 TanStack Virtual 製作 grid 排列的虛擬滾動讀取

專案筆記|2024 六角學院NodeJS 入門班結業

終於把三個月左右的直播班上完,並繳交期末作業了,趁記憶還猶新時把這次直撥班的作業記錄下來。 前言動機 從今年開始比較積極為了累積作品開始做side project,但目前線上有的開源API 能做寫入的實在太少,且雖然工作上有與後端工程師配合所以大概有DB與Modal的概念,但還是希望自己能親自寫過一次CRUD,所以報名了今年六角學院Node.js入門班,也趁機拿一個前後端較為完整的side Pro

Jun 16, 20241 min read
專案筆記|2024 六角學院NodeJS 入門班結業

拿鐵癌末期 | HANNAH's Blog

9 posts