面試官: 談一談 HOC、Render props、Hooks
- 2020 年 3 月 11 日
- 筆記
在以前我們可能會看到很多文章在分析 HOC 和 render props, 但是在 2020 年 ,我們有了新歡 「hook」 .
本篇文章會分析 hook , render props 和 HOC 三種模式的優缺點. 讓你徹底理解這三種模式. 並且, 告訴你為何應該儘可能使用 hook.
HOC
創建 HOC 的方式
學習 HOC 我們只需要記住以下 2 點定義:
- 創建一個函數, 該函數接收一個組件作為輸入除了組件, 還可以傳遞其他的參數
- 基於該組件返回了一個不同的組件.
程式碼如下:
function withSubscription(WrappedComponent, selectData) { return class extends React.Component { constructor(props) { super(props); this.state = { data: selectData(DataSource, props) }; } // 一些通用的邏輯處理 render() { // ... 並使用新數據渲染被包裝的組件! return <WrappedComponent data={this.state.data} {...this.props} />; } }; }
HOC 的優點
- 不會影響內層組件的狀態, 降低了耦合度
HOC 的缺點
- 固定的 props 可能會被覆蓋.
<MyComponent x="a" y="b" />
這 2 個值,如果跟高階組件的值相同, 那麼 x,y 都會被來自高階組件的值覆蓋.
// 如果 withMouse 和 withPage 使用了同樣的 props, 比如 x , y. // 則會有衝突. export default withMouse(withPage(MyComponent));
- 它無法清晰地標識數據的來源
withMouse(MyComponent) 它不會告訴你組件中包含了哪些 props , 增加了調試和修復程式碼的時間.
render props
功能: 將一個組件內的 state 作為 props 傳遞給調用者, 調用者可以動態的決定如何渲染.
創建 render props 的方式
- 接收一個外部傳遞進來的 props 屬性
- 將內部的 state 作為參數傳遞給調用組件的 props 屬性方法.
程式碼如下:
class Mouse extends React.Component { constructor(props) { super(props); this.state = { x: 0, y: 0 }; } render() { return ( <div style={{ height: '100%' }}> // 使用 render props 屬性來確定要渲染的內容 {this.props.render(this.state)} </div> ); } } // 調用方式: <Mouse render={mouse => ( <p>滑鼠的位置是 {mouse.x},{mouse.y}</p> )}/>
缺點
- 無法在 return 語句外訪問數據
它不允許在 return 語句之外使用它的數據. 比如上面的例子, 不能在 useEffect 鉤子或組件中的任何其他地方使用 x 和 y 值, 只能在 return 語句中訪問.
- 嵌套
它很容易導致嵌套地獄. 如下程式碼:
const MyComponent = () => { return ( <Mouse> {({ x, y }) => ( <Page> {({ x: pageX, y: pageY }) => ( <Connection> {({ api }) => { // yikes }} </Connection> )} </Page> )} </Mouse> ) };
基於上面的兩種方式,都有他們的缺點,那我們來到最香的解決方案: hook
hook
我們來看一個例子:
const { x, y } = useMouse(); const { x: pageX, y: pageY } = usePage(); useEffect(() => { }, [pageX, pageY]);
從上面的程式碼可以看出, hook 有以下的特性. 它解決了上面 hoc 和 render props 的缺點.
- hook 可以重命名
如果 2 個 hook 暴露的參數一樣,我們可以簡單地進行重命名.
- hook 會清晰地標註來源
從上面的例子可以簡單地看到, x 和 y 來源於 useMouse. 下面的 x, y 來源於 usePage.
- hook 可以讓你在 return 之外使用數據
- hook 不會嵌套
- 簡單易懂, 對比 hoc 和 render props 兩種方式, 它非常直觀, 也更容易理解.
總結
在 hook、render props 和 HOC(higher-order components) 之間選擇時,應該儘可能使用 hook.
參考資料
[1]
參考文章: https://dev.to/bettercodingacademy/react-hooks-vs-render-props-vs-higher-order-components-1al0