HoC 不屬於 React 的 API,它是一種實現模式,本質上是一個函數,接受一個或多個 React 組件做爲參數,返回一個全新的 React 組件,而不是改造現有的組件,這樣的組件被稱爲高階組件。開發過程當中,有的功能須要在多個組件類複用時,這時能夠建立一個 Hoc。javascript
const HoC = (WrappendComponent) => {
const WrappingComponent = (props) => (
<div className="container"> <WrappendComponent {...props} /> </div> ); return WrappingComponent; }; 複製代碼
上述代碼中,接受 WrappendComponent 做爲參數,此參數就是將要被 HoC 包裝的普通組件,在 render 中包裹一個 div,賦予它 className
屬性,最終產生的 WrappingComponent 和 傳入的 WrappendComponent 是兩個徹底不一樣的組件。html
在 WrappingComponent 中,能夠讀取、添加、編輯、刪除傳給 WrappendComponent 的 props
,也能夠用其它元素包裹 WrappendComponent,用來實現封裝樣式、添加布局或其它操做。前端
const HoC = (WrappedComponent, LoginView) => {
const WrappingComponent = () => {
const {user} = this.props;
if (user) {
return <WrappedComponent {...this.props} />
} else {
return <LoginView {...this.props} />
}
};
return WrappingComponent;
};
複製代碼
上述代碼中有兩個組件,WrappedComponent 和 LoginView,若是傳入的 props
中存在 user
,則正常顯示的 WrappedComponent 組件,不然顯示 LoginView 組件,讓用戶去登陸。HoC 傳遞的參數能夠爲多個,傳遞多個組件定製新組件的行爲,例如用戶登陸狀態下顯示主頁面,未登陸顯示登陸界面;在渲染列表時,傳入 List 和 Loading 組件,爲新組件添加加載中的行爲。java
const HoC = (WrappendComponent) => {
class WrappingComponent extends WrappendComponent {
render() (
const {user, ...otherProps} = this.props;
this.props = otherProps;
return super.render();
}
}
return WrappingComponent;
};
複製代碼
WrappingComponent 是一個新組件,它繼承自 WrappendComponent,共享父級的函數和屬性。可使用 super.render() 或者 super.componentWillUpdate() 調用父級的生命週期函數,可是這樣會讓兩個組件耦合在一塊兒,下降組件的複用性。react
React 中對組件的封裝是按照最小可用單元的思想來進行封裝的,理想狀況下,一個組件只作一件事情,符合 OOP
中的單一職責原則。若是須要對組件的功能加強,經過組合的方式或者添加代碼的方式對組件進行加強,而不是修改原有的代碼。算法
render() {
// 每一次render函數調用都會建立一個新的EnhancedComponent實例
// EnhancedComponent1 !== EnhancedComponent2
const EnhancedComponent = enhance(MyComponent);
// 每一次都會使子對象樹徹底被卸載或移除
return <EnhancedComponent />; } 複製代碼
React 中的 diff
算法會比較新舊子對象樹,肯定是否更新現有的子對象樹或丟掉現有的子樹並從新掛載。微信
// 定義靜態方法
WrappedComponent.staticMethod = function() {/*...*/}
// 使用高階組件
const EnhancedComponent = enhance(WrappedComponent);
// 加強型組件沒有靜態方法
typeof EnhancedComponent.staticMethod === 'undefined' // true
複製代碼
HoC中指定的 ref
,並不會傳遞到子組件,須要經過回調函數使用 props
傳遞。app
關注微信公衆號:創宇前端(KnownsecFED),碼上獲取更多優質乾貨!函數