首先打個廣告,系列文章:
下面進入正題:
什麼是HOC
我們寫的純函式元件只負責處理展示,很多時候會發現,由於業務需求,元件需要被“增強”,例如響應瀏覽器事件等。如果只有一兩個元件我們大可以全部重寫為class形式,但如果有許多元件需要進行相似或相同的處理(例如都響應瀏覽器視窗改變這個事件)時,考慮到程式碼的複用性,很容易想到用函式處理,HOC也正是為了解決這樣的問題而出現的。
說白了,高階元件的存在和React mixins類似,都是為了解決程式碼複用的問題。
基本原理
HOC高階元件的基本原理可以寫成這樣:
const HOCFactory = (Component) => {
return class HOC extends React.Component {
render(){
return <Component {...this.props} />
}
}
}
複製程式碼
很明顯HOC最大的特點就是:接受一個元件作為引數,返回一個新的元件。
舉個?
我們還沿用上篇文章中響應滑鼠事件的的?。
import React from 'react'
import ReactDOM from 'react-dom'
const withMouse = (Component) => {
return class extends React.Component {
state = { x: 0, y: 0 }
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
<Component {...this.props} mouse={this.state}/>
</div>
)
}
}
}
// APP是一個純函式無狀態元件
const App = (props) => {
const { x, y } = props.mouse
return (
<div style={{ height: '100%' }}>
<h1>The mouse position is ({x}, {y})</h1>
</div>
)
}
const AppWithMouse = withMouse(App)
ReactDOM.render(<AppWithMouse/>, document.getElementById('root'))
複製程式碼
優劣分析
優點:
- 支援ES6,光這一項就戰勝了mixins
- 複用性強,HOC是純函式且返回值仍為元件,在使用時可以多層巢狀,在不同情境下使用特定的HOC組合也方便除錯。
- 同樣由於HOC是純函式,支援傳入多個引數,增強了其適用範圍。
當然HOC也存在一些問題(不然我就不會寫這篇文章了...)
- 當有多個HOC一同使用時,無法直接判斷子元件的props是哪個HOC負責傳遞的。
- 重複命名的問題:若父子元件有同樣名稱的props,或使用的多個HOC中存在相同名稱的props,則存在覆蓋問題,而且react並不會報錯。當然可以通過規範名稱空間的方式避免。
- 可以發現HOC產生了許多無用的元件,加深了元件層級。
所以即使React HOC(高階元件)比古老的React mixins在解決程式碼複用問題上進步了不少,但是依然不能令人滿意。進一步的方案,參考下篇文章:React render props。