React 高階組件介紹

高階組件的定義

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() {
  // 每一次render函數調用都會建立一個新的EnhancedComponent實例
  // EnhancedComponent1 !== EnhancedComponent2
  const EnhancedComponent = enhance(MyComponent);
  // 每一次都會使子對象樹徹底被卸載或移除
  return <EnhancedComponent />; } 複製代碼

React 中的 diff 算法會比較新舊子對象樹,肯定是否更新現有的子對象樹或丟掉現有的子樹並從新掛載。微信

  • 必須將靜態方法作拷貝
// 定義靜態方法
WrappedComponent.staticMethod = function() {/*...*/}
// 使用高階組件
const EnhancedComponent = enhance(WrappedComponent);

// 加強型組件沒有靜態方法
typeof EnhancedComponent.staticMethod === 'undefined' // true
複製代碼
  • Refs屬性不能傳遞

HoC中指定的 ref,並不會傳遞到子組件,須要經過回調函數使用 props 傳遞。app

參考連接


關注微信公衆號:創宇前端(KnownsecFED),碼上獲取更多優質乾貨!函數

相關文章
相關標籤/搜索