iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 6
2
Modern Web

TypeScript + React + 雜七雜八系列 第 6

【Day 06】React Hooks,custom Hook

  • 分享至 

  • xImage
  •  

大家好,今天的篇章要介紹的是 custom Hook

會延續前一天的專案結構接續下去進行修改,如果沒有參與到昨天的建置過程,這邊也有提供原始碼
https://github.com/littlehorseboy/typescript-react/tree/day5-usestate-useeffect


先整理個一下

首先呢,我想要將昨天建置的三個 component 給換個目錄位置放

- src/components/Counter/Counter.tsx
- src/components/GetUUID/GetUUID.tsx
- src/components/GetUUIDByMultipleOfFive/GetUUIDByMultipleOfFive.tsx
+ src/components/day05/Counter/Counter.tsx
+ src/components/day05/GetUUID/GetUUID.tsx
+ src/components/day05/GetUUIDByMultipleOfFive/GetUUIDByMultipleOfFive.tsx

移至 src/components/day05/ 底下,只是為了後續的章節不要讓專案越來越紊亂而改的結構,雖然也不保證最後會有多麼的整齊 XD,記得 Root.tsx 的引用路徑也要更正,不對,其實就直接將它們刪掉就好,因為要實作新的 component,那三個 component 就暫時擺旁邊了

custom Hook

進入主題,React Hooks 提供了一個強大的功能能夠提取狀態邏輯來達到 reuse 的效果,可以替代原本提供可重用邏輯的兩種方案

  1. 透過父組件 render props
  2. HOC

寫起來非常的簡單,就是新增一個 function 回傳利用 useState 宣告的變數,還可以利用 useEffect 來實作一些非同步邏輯,以下就先新增一個 .ts

+ src/components/day06/useGetUUID.ts

useGetUUID 的 use 開頭是 custom Hook 約定成俗的命名規則

長的跟前面的 .tsx 做的 component 非常的相像對吧?不過最後這個 function 要 return 的值是 string 型別的 state 資料,中間還實作了 useEffect 去 ajax 取得資料,之前有提到 useState 用第二個函式改變 state 時會使 functional component 做 rerender 的動作,在某個組件使用了這個 custom Hook 時,也一樣會讓因為這裡改變了 state 而進行 rerender。

特別看一下 setUuidString 的型別

接下來我們要新增兩個 component 來展示使用 useGetUUID 的過程

+ src/components/day06/UUIDStatus/UUIDStatus.tsx
+ src/components/day06/UUIDList/UUIDList.tsx

檔案內容分別為

兩個 component 都直接在各自 function 區塊內使用 useGetUUID()

然後直接來看執行結果

相信各位可以看得出,兩個 component 分別調用了 useGetUUID() 後,各自也因為 custom Hooks 的 React.SetStateAction 有非同步執行,而 rerender 出了結果。

筆者其實是看到 Building Your Own Hooks 而突然一個感興趣的實作,這個實作示例感覺上可能有些不能揣摩出實際且好用的應用情境,不過也算是小小推進了瞭解有許多熱門的 React 第三方函式庫,是怎麼樣去封裝他們自己的 custom Hook。

最後附上原始碼
https://github.com/littlehorseboy/typescript-react/tree/day06-custom-hook


明天會再介紹其它的 Hooks 們的使用


上一篇
【Day 05】React Hooks,useState 與 useEffect
下一篇
【Day 07】React Hooks,useRef 與 useMemo 與 useCallback
系列文
TypeScript + React + 雜七雜八30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言