1. 程式人生 > 其它 >React: 高階元件 (HOC)

React: 高階元件 (HOC)

React:高階元件(HOC)

概念

  • 高階元件(HOC,Higher-Order Components)不是元件,而是一個函式,它會接收一個元件作為引數並返回一個經過改造的新元件:
const EnhancedComponent = HOC(WrappedComponent);
  • 需要區分的是,元件是將 props 轉換為 UI,而高階元件是將元件轉換為另一個元件;
  • 高階元件是 React 中用於複用元件邏輯的一種高階技巧;

實現方式

屬性代理

屬性代理是最常見的實現方式,它本質上是使用組合的方式,通過將元件包裝在容器元件中實現功能。
屬性代理方式實現的高階元件和原元件的生命週期關係完全是React父子元件的生命週期關係,所以該方式實現的高階元件會影響原元件某些生命週期等方法。

優點:

  1. 正常屬性代理可以和業務元件低耦合,零耦合,對於條件渲染和props屬性增強,只負責控制子元件渲染和傳遞額外的props就可以,所以無須知道,業務元件做了些什麼。所以正向屬性代理,更適合做一些開源專案的hoc,目前開源的HOC基本都是通過這個模式實現的。

  2. 同樣適用於class宣告元件,和function宣告的元件。

  3. 可以完全隔離業務元件的渲染,相比反向繼承,屬性代理這種模式。可以完全控制業務元件渲染與否,可以避免反向繼承帶來一些副作用,比如生命週期的執行。

  4. 可以巢狀使用,多個hoc是可以巢狀使用的,而且一般不會限制包裝HOC的先後順序。

缺點:

  1. 一般無法直接獲取業務元件的狀態,如果想要獲取,需要ref獲取元件例項。

  2. 無法直接繼承靜態屬性。如果需要繼承需要手動處理,或者引入第三方庫。

反向繼承

反向繼承指的是使用一個函式接受一個元件作為引數傳入,並返回一個繼承了該傳入元件的類元件,且在返回元件的 render() 方法中返回 super.render() 方法

-> 1,裝飾元件直接傳入

-> 2,super.render( ) 呼叫

優點:

  1. 方便獲取元件內部狀態,比如state,props ,生命週期,繫結的事件函式等

  2. es6繼承可以良好繼承靜態屬性。我們無須對靜態屬性和方法進行額外的處理。

缺點:

  1. 無狀態元件無法使用。

  2. 和被包裝的元件強耦合,需要知道被包裝的元件的內部狀態,具體是做什麼?

  3. 如果多個反向繼承hoc巢狀在一起,當前狀態會覆蓋上一個狀態。這樣帶來的隱患是非常大的,比如說有多個componentDidMount,當前componentDidMount會覆蓋上一個componentDidMount。這樣副作用串聯起來,影響很大。