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

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

主要引用內容皆來自於🔗 [2020/12/21-Introducing Zero-Bundle-Size React Server Components](https://react.dev/blog/2020/12/21/data-fetching-with-react-server-components)

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

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

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

```javascript
// ⬇️ 因為需要從一隻 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>
);
```

理想上，我們希望我們的代碼長這樣：

```javascript
// 只需要根據知道目前 Page 的 artisId
function ArtistPage({ artistId }) {
  return (
    <ArtistDetails artistId={artistId}>
      <TopTracks artistId={artistId} />
      <Discography artistId={artistId} />
    </ArtistDetails>
  );
}
```

```javascript
// 🌟 並且我們在元件中，自行決定我們要獲取什麼數據
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，在小型的應用程式我們很難做到這件事，在大公司也需要後端技術的配合

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1742660174981/1195278f-0ab7-4f4c-9a97-55d5f9a8ae55.png align="center")

原本的寫法會造成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。
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1742660426446/7850b183-3387-488d-8cfe-334ad2f81dbb.png align="center")

*   根據具體的情況來使用 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。
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1742660472611/f2af9ec1-6019-487e-aed8-a35a7826a304.png align="center")
