首頁 >web前端 >js教程 >淺談React高階組件

淺談React高階組件

亚连
亚连原創
2018-05-28 16:42:431573瀏覽

這篇文章主要介紹了淺談React高階組件,現在分享給大家,也給大家做個參考。

前段時間在工作中寫Hybrid頁面時遇到了這樣的一個場景,公司需要一系列的活動元件,在每個元件註冊的時候都需要呼叫App端提供的一個介面。一開始也考慮了幾種方式,包括mixin、元件繼承以及react高階元件。但經過了種種衡量,最後選擇使用了高階組件的做法。

那什麼是高階元件?首先你得先了解請求ES6中的class只是語法糖,本質還是原型繼承。能夠更好的進行說明,我們將不會修改組件的程式碼。而是透過提供一些能夠包裹組件的組件, 並透過一些額外的功能來增強組件。這樣的組件我們稱之為高階組件(Higher-Order Component)。

1、Mixins的缺點

React官方已不推薦使用Mixins的技術來實現程式碼的重用,Mixins技術有一系列的缺點,首先Mixins會造成命名衝突,我們透過以下的方式來注入Mixins:

var myMixins = require('myMixins');

var Button = React.createClass({
  mixins: [myMixins],
  
  // ...
})

#如果你需要注入多個mixins,其中一個是自己的,另外的可能是第三方的。那有可能在兩個mixins裡使用了相同名稱的方法,這會使得其中的一個不起作用,而你能做的只有修改其中一個方法的名稱。另一方面,一個mixins一開始可能是非常簡單的,僅僅需要實作某一個功能,但當業務越加的複雜,需要往其中加入更多的方法的時候,就會變得非常複雜。要深入了解mixins的缺點,可以查看官方部落格。

2、元件繼承

對我自己來說這種方法以前使用的比較多,先建立一個BaseComponent,在其中實作一系列公共的方法,其後的每個元件都繼承於這個元件,但缺點是不夠靈活,在基礎元件中只能實作一些比較固定的方法,而對於每個元件的客製化會有很大的限制。

3、React高階元件

由於mixins的一系列缺點,React官方也意識到使用mixins所帶來的痛點遠高於技術本身產生的優點,而高階組件可以取代mixins,而且當深入之後它還有著更豐富的用法。

高階元件(HOC)是React中對元件邏輯進行重複使用的高階技術。但高階元件本身並不是React API。它只是一種模式,這種模式是由React自身的組合性質必然產生的。

高階函數

說到高階元件,就先得說到高階函數了,高階函數是至少滿足下列條件的函數:

1、接受一個或多個函數為輸入
2、輸出一個函數

在javascript這門函數為一等公民的語言中,高階函數的使用還是非常多的,像我們平常的回呼函數等等,都用到了高階函數的知識。我們先來看一個簡單的高階函數

var fun = function(x, y) {
  return x + y;
}

fun是一個函數,下面我們將整個函數當作參數傳遞給另一個函數

var comp = function(x, y, f) {
  return f(x,y);
}

驗證一下

comp(1,2,fun) // 3

高階元件定義

##類比高階函數的定義,高階元件就是接受一個元件作為參數,在函數中對元件做一系列的處理,然後再傳回一個新的元件作為回傳值。

我們先定義一個高階元件BaseActivity

const BaseActivity = (WrappedComponent) => {
 return class extends Component {
  render() {
   return (
    <section>
     <p>我的包裹组件</p>
     <WrappedComponent />
    </section>
    
   )
  }
 }
}

元件接受一個被包裹的元件作為參數,傳回了一個經過處理的匿名組件。


在其他元件中使用這個高階元件

class Example extends React.PureComponent {
 constructor(props) {
  super(props);
  this.state = {
   width: &#39;100%&#39;,
   height: &#39;100%&#39;
  }
 }

 componentWillMount() {
  if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
   return;
  } else {
   this.setState({
    width: &#39;375px&#39;,
    height: &#39;640px&#39;
   })
  }
 }

 render() {
  let { width, height } = this.state;
  return (
   <p className="activity">
    <p className="activity-content" style={{ width, height }}>
     <button className="btn">参加活动</button>
    </p>
   </p>
  )
 }
}

export default BaseActivity(Example);

具體用法就是在export 元件的時候,使用BaseActivity函數來包裹這個元件,看下輸出的react dom內容


#在Example元件外麵包了一個匿名元件。

參數

既然高階元件是函數,我們就可以向裡面傳遞我們需要的參數

const BaseActivity = (WrappedComponent, title) => {
 return class extends Component {
  render() {
   return (
    <section>
     <p>{title}</p>
     <WrappedComponent />
    </section>
    
   )
  }
 }
}

在Example中這樣export

export default BaseActivity(Example, &#39;这是高阶组件的参数&#39;);

#我們看下輸出的react dom


可以看到參數已經傳遞進去了。

當然還可以這樣用(柯里化)

const BaseActivity (title) => (WrappedComponent) => {
 return class extends Component {
  render() {
   return (
    <section>
     <p>{title}</p>
     <WrappedComponent />
    </section>
    
   )
  }
 }
}

#在Example中這樣export

export default BaseActivity(&#39;这是高阶组件的参数&#39;)(Example);

這種用法在ant-design的表單以及redux的connect中我們都可以看到

// ant
const WrappedDemo = Form.create()(Demo)

// redux
export default connect(mapStateToProps, mapDispatchToProps)(Counter)

高階元件也可以擴充原始元件的props屬性,如下所示:

const BaseActivity (title) => (WrappedComponent) => {
 return class extends Component {
  render() {
   const newProps = {
     id: Math.random().toString(8)
   }
   return (
    <section>
     <p>{title}</p>
     <WrappedComponent {...this.props} {...newProps}/>
    </section>
   )
  }
 }
}

#看下輸出的react dom


高階元件的缺點

#高階元件也有一系列的缺點,首先是被包覆元件的靜態方法會消失,這其實也是很好理解的,我們將元件當作參數傳入函數中,傳回的已經不是原來的元件,而是一個新的元件,原來的靜態方法自然就不存在了。如果需要保留,我們可以手動將原始組件的方法拷貝給新的元件,或使用hoist-non-react-statics之類的函式庫來進行拷貝。

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

Ajax取得回應內容長度的方法

Ajax方式實作定期更新頁面某塊內容的方法

ajax讀取properties資源檔案資料的方法

以上是淺談React高階組件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn