Custom Hook
你以為你在寫 Custom Hook,但其實只是在寫 utils | KK
之前好像有寫過筆記但不見了,重看一次...
小技巧
- custom hook return 包大括弧 eg.
return { users }
,回傳 data 以外的資訊- BAD:
return users
- GOOD:
{ users, error, loading, refetch }
- BAD:
- custom hook 以資源方式封裝
- hook 裡面只有一個 fetch 是 over engineering。eg. 寫一堆 useCreateUser 這樣的東西
- 建議操作 resource => useUser,裡面有 CRUD,把動作跟資料封裝進一個 hook,而不是一個動作寫一個 hook
- 推薦學習 https://usehooks.com/ 的 useAuth
- 注意 data reuse
- 如果一個頁面要 map 很多 userID 就會發一堆 request
- 延伸閱讀:
- useContext+useReducer, redux https://dev.to/kexinlin/use-usereducer-usecontext-to-replace-redux-23lo
- swr, useQuery https://dev.to/lvieira268/swr-vs-react-query-5el0
常見錯誤:
- 把 side effect(會對其他程式碼造成影響)、async 分不清楚
- useEffect 裡面是放 side effect,有的人在裡面放單純 local storage 更新
useEffect
都 2022 年了你可能還是不懂 useEffect | Zet
一開始有點雜音,後面有修掉。
Function & class component 你可能不知道的關鍵區別
Demo
this.props.user 是 mutable 的方式。他不會記得觸發拿時間的資料,會拿到三秒後的資料。所以觸發時間點的 this.props.user 要找個地方存起來。
Functional Component 每一次 render 都有他自己的連鎖資料流
class component 基於 OOP,以 mutable 的方式存取 this.props&this.state
functional component 基於 FP,每次都會重新執行函數並傳入獨立參數的方式來存取 props&state
每次 render 都有自己的資料狀態(props&state)、event hanler,不會互相影響
effect 也是屬於某次 render,effect 是利用 closures 的方式看到不一樣的原始資料
當依賴的值是常數 closures 好理解,但依賴的值是 mutible 時可能發生意外。
FP 好理解,但犧牲了效能,每次 render 都有自己獨立的資料。
clean up
- 真正學會 useEffect 的第一步:忘記 class component 的生命週期
- 不要欺騙 hooks 的 dependencies chain
- useReducer 是 dependencies chain 的合法作弊手段
- 以 dependencies 來控制 useEffect 執行邏輯的誤區
React 18 「reusable state」
- Reusable state — React 18 的 useEffect 在 mount 時為何會執行兩次?
https://slides.com/tz5514/useeffect-guide
strict mode + dev env
總結
- useEffect 的正確用途
Function component 沒有生命週期的 API,只有 useEffect 用於「從資料同步到 effect 的行為與影響」
useEffect 讓你根據目前的資料來同步 React elements(畫面)以外的任何事物
useEffect 是隨著每次 render 後而自動觸發的 - 預設情況下,每一次 render 後都應該執行屬於該 render 的 useEffect,來確保同步的正確性與完整性
useEffect 的 dependencies 是一種「忽略某些不必要的同步」的效能最佳化,而不是用來控制 effect 發生在特定的 component 生命週期,或特定的商業邏輯時機
確保你有自己寫邏輯來讓 effect 在你預期的條件情境時才執行,而不該依靠 dependencies 來控制這件事情 - useEffect 應設計成即使多次重複執行也有保持邏輯行為正確的彈性
確保你的 useEffect 無論隨著 render 重新執行了幾次,你的程式結果都應該保持同步且正常運作
Strict mode + dev 環境時, component 會自動被 mount 兩次。這是在模擬「mount => unmount => mount 」的過程, 幫助開發者檢查 effect 的設計是否滿足這個彈性的要求
如果 effect 多次執行會導致問題,可以優先考慮實作 effect 的 cleanup function 來停止或逆轉 effect 中造成的影響