# useContext 常犯錯誤與如何在 TS 使用 <iframe width="560" height="315" src="https://www.youtube.com/embed/I7dwJxGuGYQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> :::spoiler 目錄 [TOC] ::: ## TL;DR - 在使用 useContext 時,一定要將其包裝成 custom hook - [React 官方文件新增了 TypeScript 使用專文](https://react.dev/learn/typescript?fbclid=IwAR3Pgkr8xpS48Vwa0ADo3oagaAPKX1q05jHhtbXH8ltV8MKwa8FAvePoXPU) - [英文版本](https://jason60810.hashnode.dev/always-use-a-custom-hook-for-context-api-not-usecontext-react-context-api-typescript) ## 資料夾結構 ( 使用 next app route )  ### theme-context.tsx 一定要加上 `use client`,因為 useState 只能在 client component 運作 , **特別注意,就算這裡加了`use client`,所有的子層還是 server component (預設)**  ### layout.tsx 加上 provider 之後,下面所有的子層都可以拿到值,不用用 prop 一個一個傳下去  ### page.tsx  ### logo.tsx 1. 因為 useContext 要在 client component 運作,所以要加上 `use client`。 2. 當使用 useContext 時,一定要引入 ThemeContext,用起來很麻煩 3. 因為 ThemeContext 預設是 null,所以當不是在 provider 裡使用 `useContext` 時 ( Logo component ),會發生錯誤,因此需要先確認有 context  舉例:不是在 provider 裡使用 `useContext`  ### 創建 custom hook  ### 使用 custom hook 現在引入 ThemeContext 和處理錯誤的問題,已經抽離到 custom hook 中  ### 加上型別 1. React.ReactNode,可以接受 JavaScript primitives ,如果只想要是 jsx 可以使用 React.ReactElement ( [react 官方文件](https://react.dev/learn/typescript#typing-children) ) 2. `type Theme` 可以讓 `useState` 在 get 和 set 時,可以使用正確的型別,例如:當想要 `setTheme('blue')` 時,會報錯,因為 `type Theme` 只有 'dark' 和 'light' 3. 在給予 createContext 型別時,可以利用 ts 的 union 讓 createContext 知道可能有 null 這個型別 ( [react 官方文件](https://react.dev/learn/typescript#typing-usecontext) ) 
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.