You're importing a component that needs `useState`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive.
這個錯誤發生的原因是 React Server Components 和 Client Components 的區別:
- Server Components (預設) 不能使用 hooks、瀏覽器 API 等 client-side 功能
useState
是 client-side hook,只能在 Client Components 使用- 要使用
useState
,需在檔案頂部加入"use client"
指令,將組件標記為 Client Component
"use client"
import { useState } from 'react'
export default function Component() {
const [state, setState] = useState()
// ...
}
React 渲染方式的差異:Vanilla React vs. Next.js
當使用 Vanilla React 應用時,渲染是在 客戶端 進行的:
- 伺服器端:只返回一個 HTML 文件,其中包含客戶端的 JavaScript 程式碼。
- 客戶端:利用這些 JavaScript 程式碼生成並渲染頁面上的可見內容。
相對而言,Next.js 是一個全棧框架,不僅包括前端還涵蓋後端,因此程式碼也會在 伺服器端 執行:
- 伺服器端:執行伺服器端的組件函數,生成要渲染的 HTML 程式碼。
- 客戶端:接收伺服器返回的 HTML 程式碼,並負責渲染內容。
默認情況下,Next.js 項目中的所有 React 組件(例如 page
、layout
等)都是在 伺服器端渲染 的。也就是說,Next.js 應用中的所有 React 組件默認都是伺服器端組件(RSCs)。
Server vs Client Components
React Server Components (RSC)
- 組件僅在伺服器端渲染。
- Next.js 預設所有 React 組件為 RSC。
- 只有在使用像 Next.js 這樣的框架時才能工作和使用。
- 減少需要下載的客戶端 JavaScript 程式碼,提升網站性能。
- 有利於 SEO,因為搜尋引擎爬蟲可以抓取包含完整內容的頁面。
Client Components
- 組件在伺服器端預渲染後,還會在客戶端進行渲染。
- 必須在客戶端渲染,適用於需要執行客戶端功能的組件(如 hooks、事件處理等)。
- 需要在檔案頂部添加
"use client"
。