{"content":{"title":"水分子社區（HOH）前端共學營 - 筆記(4)","body":"第二周筆記 - Server Component 與 Client Component\r\n\r\n當大家使用到Nextjs時，看到不同介紹和文檔時，在內容中都會經常見到 Server Component 與 Client Component，然而大家又對它們有多少了解呢? \r\n為了讓大家進一步了解，我就整理了相關資訊作出初步介紹。\r\n\r\n在探討它們之前，首先要認識什麼是Server與Client。\r\n\r\n![20250131_1.avif](https://img.learnblockchain.cn/attachments/2025/01/yBBDhqHB679c10755d718.avif)\r\n\r\n## Server (伺服器) 與 Client (客戶端)\r\nServer (伺服器) 就是指數據中心中的計算機，它主要是用於儲存應用程式程式碼、接收來自客戶端的請求、執行一些計算過程然後將結果發出去。\r\n Client (客戶端) 是指用戶設備上的瀏覽器，它會向伺服器發送請求，然後從伺服器接收到的回應(想要的結果)，之後再轉換合適的格式，然後展示在用戶介面上。\r\n \r\n## Server Component\r\n在 Nextjs 項目下的 app 目錄中，所有 component 都會被預設為 Server Component，而 Server Component 和 Client Component 可以同時存在相同的地方(文件夾)。開發者可以自行選擇不同的 component 想要渲染的環境。\r\n在 Server Component 中的 component 可以保證只在 server side 進行渲染。\r\n\r\n## Client Component\r\n在 Client Component 中的 component 會主要在 client side 進行渲染，不過 Next.js 中可以在 server side 預渲染，完成之後再於 client side 進行混合使用。\r\n\r\n然而，在使用  Client Component 時會有限制，例如: 在 Client Component 裡是不能直接使用 Server Component，需要透過其他方式引入使用。因為 Client Component 是在 Server Component 之後渲染，在渲染 Client Component 時沒辦法回頭渲染 Server Component。\r\n\r\n```\r\n'use client';\r\n\r\n// 這是錯誤的例子\r\nimport ServerComponent from './ServerComponent';\r\n\r\nexport default function ClientComponent() {\r\n  return (\r\n    <div>\r\n        <ServerComponent />\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n因此以上的寫法是不可行的，會出現報錯。\r\n\r\n## 怎樣在 Client Component 使用 Server Component ?\r\n\r\n如果要使用 Server Component 的話，就不能直接使用，而是要以 children props 的形式把Server Component 傳入，方法如下:\r\n\r\n### 例子1\r\n1. 首先假設 Server Component 是 app/ServerComponent.tsx\r\n```\r\nexport default function ServerComponent() {\r\n    return (\r\n      <div>\r\n          This is ServerComponent\r\n      </div>\r\n    );\r\n  }\r\n```\r\n\r\n2. 修改 app/ClientComponent.tsx\r\n```\r\n'use client';\r\n\r\n//import ServerComponent from './ServerComponent';\r\n\r\nexport default function ClientComponent({children}:any) {\r\n  return (\r\n    <div>\r\n        {children}\r\n    </div>\r\n  );\r\n}\r\n```\r\n3. 修改 Page.tsx\r\n```\r\nimport ServerComponent from './ServerComponent';\r\nimport ClientComponent from './ClientComponent'\r\n\r\nexport default function Home() {\r\n  return (\r\n    <ClientComponent>\r\n      <ServerComponent />\r\n    </ClientComponent>\r\n  )\r\n}\r\n```\r\n4. 執行項目\r\n```\r\nnpm run dev\r\n```\r\n5. 打開 http://localhost:3000/\r\n\r\n![螢幕擷取畫面 2025-01-31 111603.png](https://img.learnblockchain.cn/attachments/2025/01/DS8gwzVR679c4082b1c03.png)\r\n\r\n如果能看到以上畫面就表示成功。\r\n\r\n## 怎樣判斷在什麼時候用 Client Component / Server Component ?\r\n\r\n<!--StartFragment-->\r\n\r\n| 情況                                                                  | Server Component | Client Component |\r\n| ------------------------------------------------------------------- | ---------------- | ---------------- |\r\n| 獲取數據 (fetch data)                                                               | ✅                | ❌                |\r\n| 直接訪問後端資源 (access backend resources)                                                            | ✅                | ❌                |\r\n| 在 server 上儲存敏感信息 (access tokens, API keys, etc)                   | ✅                | ❌                |\r\n| 將大型依賴(dependencies)保留在服務器上 / 減少 client side 的 JavaScript                              | ✅                | ❌                |\r\n| 加入互動性(interactivity)及監聽事件(onClick(), onChange(), etc)                              | ❌                | ✅                |\r\n| 使用 (useState(), useReducer(), useEffect(), etc) | ❌                | ✅                |\r\n| 使用 browser-only APIs ( localStorage, XMLHttpRequest, etc)           | ❌                | ✅                |\r\n| 使用自定義的 hooks                  | ❌                | ✅                |\r\n| 使用 React Class components                                           | ❌                | ✅                |\r\n\r\n<!--EndFragment-->"},"author":{"user":"https://learnblockchain.cn/people/19478","address":null},"history":"bafkreifzpupaerrr7di3lvef3wfkuds6zkiwlhmwhzfjoqmytzdienksmy","timestamp":1738298111,"version":1}