Higher Order Component(HoC) 學習
本篇文章記錄為開發 side project 感想。
這陣子花了一些時間學習了關於 react 的 Higher Order Component,這個概念其實出來已經有一段時間了,但是一直沒有好好的去認識,直到最近重寫了一個 side project 才開始使用 Higher Order Component 這個概念,我自己覺得整個寫起來的體驗真的是很好,尤其是在寫測試的時候感受更加明顯!
Functional Programming 在這幾年開始流行起來,最早大概就是 Redux 採用了 大量的 functional programming 概念來減少 side effect,對於 Redux 還不認識得朋友,可以在 egghead.io 上來學習 Redux,這是由作者 Dan Abramov 所錄製的教學影片 - Getting Started with Redux,講解了許多 Redux 的核心概念,很值得學習!
關於 functional programming 我自己也還在學習摸索的階段,但可以發現在 react 的生態圈大量採用了這個概念來開發相關的應用,撇除 react,functional programming 是很值得學習的!
什麼是 HOC
Higher Order Component 稱為「高階元(組)件」,又簡稱「HOC」,主要的概念就是重複使用 Component,我們最早開始寫 react 大概主要都是像 class Counter extends React.Component { ... }
,透過繼承 React.Component
接著撰寫相關的邏輯,你可能有許多邏輯或者是 lifecycle method 在你的 class 內,當需求一直增加的時候,你可能會發現你的 class 會越長越大,這時候我們就必須適當的切出一些區塊出來,而這些區塊或許也能提供其他的 Component 做 reuse。
Higher Order Component 它其實就一個 function 取得一個 Component 並回傳新的 Component,在這個 function 內,你可以對傳入的 Componet 做不同的 enhance,而得到一個全新的 Component。
在許多教學會看到許多範例使用 compose
來對 Component 做各種組合,透過組合的方式可以讓 Component 更加的彈性,compose 是來自 functional programming 的概念:
compose(f, g)(x) => f(g(x))
也就是我們以前所學過的數學式,我們帶入一些數字:
compose(square, addOne)(1) => square(addOne(1))
我們給入的數字是 1
,我們先把這個數字加 1,接著把數字平方,我們得到 4。
換個場景思考一下,香腸是們製作出來的呢哈哈?好像跟 compose 的概念很像吧!我們把豬肉灌進去,中間透過機器處理,得到了香腸!
同理,我們傳入一個 Component 進去,透過不同的 function 來處理,最後得到一個全新的 Component,這就是 Higher Order Component。
Presentational 和 Container Component
這裡我覺得有必要提到關於 Presentational 和 Container 這兩種 Component 類型,未來你也會根據你的需要去區分這兩種 Component,這兩個 Component 的差別如以下:
資料來源:
Presentational Component | Container Component | |
---|---|---|
用途 | 怎麼看事情(markup, styles) | 怎麼做事情 (抓資料, 更新 state) |
取得資料 | 透過 props 得到資料 | 訂閱整個應用程式的 State,例如 Redux 的 connect() |
改變資料 | 透過 props 接收到的 callback | Dispatch action |
為了撰寫可以 reuse 的 Component,大多都是使用 Presentational Component,我們只關心傳進來的資料我們要怎麼去做呈現,我們透過 Container Component 去得到我們需要的 state,再把這些 state 作為 props 傳下去給各個 Presentational Component。
Side Project
這次在開發 nextjs-redux-instagram 中用到了許多蠻新的東西,包括 next.js、redux-saga 還有今天本篇要分享的 recompose,其實很早之前 redux 很流行的時候,我也透過 Instagram API 做過類似的 side project,但是那時候我寫的東西真的是有夠糟的!所以在前陣子才打算利用一些新技術來嘗試重寫。
在這個 side project 主要用的技術大概分成這三大項:
- Server Side Rendering
- Async action
- Higher Order Component
在 Server Side Rendering,我先透過 OAuth 認證,接著去跟 Instagram 取得 Access Token,必須拿到 Access Token 才可以去取得其他 API 資料。
選擇 redux-saga 主要是因為用到了 async action,但是用 redux-thunk 在做測試的時候需要做很多 mock,我覺得很麻煩,所以我就採用了 redux-saga,它可以很方便的寫測試,不需要額外的去做 mock,這讓我覺得很棒。
這次也嘗試了 recompose,感受一下 Higher Order Component 的威力,用起來真的感覺蠻棒的,我寫了幾個 Presentational Component,只關注如何去呈現資料,最後透過 compose 的方式將這些 Component 組合起來,不僅這樣,這樣讓我在測試上更加的容易。