了解 HOF (Higher-Order Function) 之後,就順便來補充他的好麻吉 Higher-Order Component (以下簡稱 HOC),因為他們概念真的很像。HOF 是 function 接受另一個 function 當成參數或 function 回傳 function,而 HOC 是作用在 Component 上。
HOC 的應用在 寫 React 時隨處可見,此篇也會以 React 為例。
A higher-order component is a function that takes a component and returns a new component.
以下就是最簡單的使用方式,可以看到 Componet 被包在另一個 Componet 裡
const App = higherOrderComponent(WrappedComponent);
實際上的 code 長這樣 ↓,其實也是蠻好理解的, higherOrderComponent
接受傳進來的 component WrappedComponent
當參數,然後回傳一個新的 React component 裡面包含 WrappedComponent
const higherOrderComponent = Component => props =>
(
<>
<h1>Hello World</h1>
<Component {...props} />
// props 會從母層傳下來 <App name='Hannah' />
</>
)
const WrappedComponent = ({ name }) => (
<p>I'm {name}</p>
)
const rootElement = document.getElementById('root');
const App = higherOrderComponent(WrappedComponent)
ReactDOM.render(<App name='Hannah' />, rootElement)
Hello World
I'm Hannah
higherOrderComponent
可以接受任何 Component,並可以不斷 Reuse(完整範例可以看 codepen)
用上面例子看不大出來 HOC 的好處
The idea with HOC is to enhance components with functions or data.
High-Order Component 可以經由不同的組合 compose、覆寫 overwrite、編輯上層資料與UI ,成為一個新元件的函式,讓元件一直被重覆利用。
例如今天我想做三種時鐘,會依據地區不同而顯示不同時鐘在 dashboard 上,傳入的 data 時間是一樣的。
三種 clock 除了會有不同長相跟不同 DOM,裡面也個別需要做一些不同的時間轉換
這時候 HOC 就派上用場了,以下只是大概示範會長怎樣
const widgetDashboard = Component => props =>
(
<>
<h1>Dashboard</h1>
<Component {...props} />
</>
)
const formatUnit = Component => ({ time, ...props }) => (
<Component {...props} time={formatToUnit(time)}} />
);
const clock = ({ time, name }) => (
// 一個時鐘的樣子
<h1>{name} {time}</h1>
)
const digitalClock = ({ time, name }) => (
// 數位時鐘的樣子
<h2>{name} {time}</h2>
)
const hourglass = ({ time }) => (
// 沙漏樣子
<h3>{time}</h3>
)
// Clock
const App = widgetDashboard(formatUnit(clock))
ReactDOM.render(<App name='Clock' time='2020-09-10'/>, rootElement)
// Digital Clock
const App = widgetDashboard(digitalClock)
ReactDOM.render(<App name='digital Clock' time='2020-09-10'/>, rootElement)
// Hourglass
const App = widgetDashboard(formatUnit(hourglass))
ReactDOM.render(<App time='2020-09-10'/>, rootElement)
你可以隨意地組合 formatUnit
、跟不同種時鐘 component
如有錯誤或需要改進的地方,拜託跟我說。
我會以最快速度修改,感謝您
O.S. 每天都在自我懷疑為何要熬夜寫文章 orz,而且今天可是週末啊
不是應該好好休息結果完全沒休息到,超想棄賽的 XD
歡迎追蹤我的部落格,除了技術文也會分享一些在矽谷工作的甘苦。
加油! 別放棄! 也別給自己太大壓力.
屯太少文章的結果,是否要一結束就該囤明年的文章
囤了,也有忘記發的,這在早期鐵人賽有網友有發生過這樣的人間慘劇.
FP 有很多精彩的可以講啦.順著自己的思路,享受一段思維激盪的旅程.
不要太在意別人的想法,或者想要仔細解釋,因為閱讀者的喜好或是觀點,
你無法掌握.這是外部因素.那就解耦合,不理啦,放飛自我吧.
發現你是鐵人賽大師,參加過六屆太厲害了~~
不是六屆,有一次是參加了幾組,還有用別的帳號寫.因為有幫友要打劫紀念的衣服.那次這個站還在改版,一整個緊張刺激啊,最怕是寫了,但是忘記發.所以都還要準備清單檢查.