Render props
What is render props ?
- 透過
呼叫 function
, 來產生 React element(s) - 與 Function Component 不同之處是
- FC 是透過
JSX
的方式去產生 React elements - FC 的名稱必須是以大寫字母開頭
- FC 是透過
可以用在哪 ?
- 當 Component 有共用邏輯時
Inversion control
Inversion of control which is basically a mechanism for the author of the API to allow the user of the API to control how things work internally
- Component 要 render 的東西由使用這個 Component 的 developer 決定時
- react-router 的 Route Component 中的 ‘render’
- react-window 的 row component
- 知道要 render 多個 row, 但是 row 的形式交給 API user 決定
- Component 要 render 的東西由使用這個 Component 的 developer 決定時
覆用共用邏輯
覆用邏輯: 抓取資料
1 | const LeaderBoard = ({ children }) => { |
Inversion control
我要吃晚餐,但我不知道要吃什麼,交給你決定
1 | const Me = ({ dinner }) => { |
1 | const App = () => { |
HOC (High order Component)
What is HOC ?
- Input Component, Output Component
- Component 的加工廠
可以用在哪 ?
- 當 Component 有共用邏輯時
覆用共用邏輯
覆用邏輯: 抓取資料
1 | function withData(Component) { |
1 | // In LeaderBoard.js |
一些可能需要注意的地方
ref forwarding
1
2
3
4
5
6
7
8
9function withData(Component) {
function Wrapper(props, ref) {
// 處理一些抓資料的邏輯, 整理後得到: data
return <Component data={data} ref={ref} {...props} />
}
return React.forwardRef(Wrapper);
}Display name in Dev tools
HOC 在 React dev-tools 時會呈現 Unkown 這個 name, 不利於我們 debug
1 | function withData(Component) { |
Render props v.s. HOC
共同點
- 覆用程式邏輯
HOC 的缺點
- 容易遇到 Naming collision problem
- 當包了多層的 HOC 時很難避免與察覺
- 當包了多個 HOC 後, 無法明確知道 props 是從何而來
1 | const FinalComponent = withA(withB(withC(withD(Component)))) |
只知道 FinalComponent 相較於 Component 會多出了許多 props, 但很難知道分別是從哪一層 HOC 加工而得
- Static composition - Component 的形式在 Compile time 就定好且無法更動
they have no effect on what is rendered, only on what data is used
- 當我們 call 了 withA(Component) 時就已決定
Render props 的優點
- 可以用在
Inversion control
這個情境下 - 任何 HOC 都可以改寫成 render props 方式
- Dynamic composition - Component 的形式可以在 run time 時動態改變
the component itself is injected and we can decide what is rendered in the render time
[補個] Composition
- 直白來說就是把 Component 們當做各個
獨立的
零件, 組合成我們的 App - 手段包含
- 透過 props.children 來組成父子 Compoennt
- 透過 props 來灌 Component 進去, 決定要 render 什麼
- render props
- HOC
- …. etc.
- 相對於 Composition, 另一種方式是 Inheritance
- 相較於 Composition 各個單元獨立, Inheritance 偏向
階層式關係
- 相較於 Composition 各個單元獨立, Inheritance 偏向
通通拿去做 Hooks
Hooks 的出現, 讓 覆用邏輯
這件事情可以更輕易地達成
1 | // render props |
1 | // hooks |
- 但是仍然有需要 render props 的時候 => 在建立一個提供
Inversion control
的 API Component 時