前段時(shí)間在工作中寫Hybrid頁(yè)面時(shí)遇到了這樣的一個(gè)場(chǎng)景,公司需要一系列的活動(dòng)組件,在每個(gè)組件注冊(cè)的時(shí)候都需要調(diào)用App端提供的一個(gè)接口。一開始也考慮了幾種方式,包括mixin、組件繼承以及react高階組件。但經(jīng)過了種種衡量,最后選擇使用了高階組件的做法。
10余年建站經(jīng)驗(yàn), 成都網(wǎng)站建設(shè)、做網(wǎng)站客戶的見證與正確選擇。創(chuàng)新互聯(lián)提供完善的營(yíng)銷型網(wǎng)頁(yè)建站明細(xì)報(bào)價(jià)表。后期開發(fā)更加便捷高效,我們致力于追求更美、更快、更規(guī)范。
那什么是高級(jí)組件?首先你得先了解請(qǐng)求ES6中的class只是語(yǔ)法糖,本質(zhì)還是原型繼承。能夠更好的進(jìn)行說明,我們將不會(huì)修改組件的代碼。而是通過提供一些能夠包裹組件的組件, 并通過一些額外的功能來增強(qiáng)組件。這樣的組件我們稱之為高階組件(Higher-Order Component)。
1、Mixins的缺點(diǎn)
React官方已不推薦使用Mixins的技術(shù)來實(shí)現(xiàn)代碼的重用,Mixins技術(shù)有一系列的缺點(diǎn),首先Mixins會(huì)造成命名沖突,我們通過以下的方式來注入Mixins:
var myMixins = require('myMixins'); var Button = React.createClass({ mixins: [myMixins], // ... })
如果你需要注入多個(gè)mixins,其中一個(gè)是自己的,另外的可能是第三方的。那有可能在兩個(gè)mixins里使用了相同名稱的方法,這會(huì)使得其中的一個(gè)不起作用,而你能做的只有修改其中一個(gè)方法的名稱。另一方面,一個(gè)mixins一開始可能是非常簡(jiǎn)單的,僅僅需要實(shí)現(xiàn)某一個(gè)功能,但當(dāng)業(yè)務(wù)越加的復(fù)雜,需要往其中加入更多的方法的時(shí)候,就會(huì)變得非常復(fù)雜。要深入了解mixins的缺點(diǎn),可以查看官方博客。
2、組件繼承
對(duì)于我自己來說這種方法以前使用的比較多,先創(chuàng)建一個(gè)BaseComponent,在其中實(shí)現(xiàn)一系列公共的方法,其后的每個(gè)組件都繼承于這個(gè)組件,但缺點(diǎn)是不夠靈活,在基礎(chǔ)組件中只能實(shí)現(xiàn)一些比較固定的方法,而對(duì)于每個(gè)組件的定制化會(huì)有很大的限制。
3、React高階組件
由于mixins的一系列缺點(diǎn),React官方也意識(shí)到使用mixins所帶來的痛點(diǎn)遠(yuǎn)遠(yuǎn)高于技術(shù)本身產(chǎn)生的優(yōu)點(diǎn),而高階組件便可以代替mixins,而且當(dāng)深入之后它還有著更加豐富的用法。
高階組件(HOC)是React中對(duì)組件邏輯進(jìn)行重用的高級(jí)技術(shù)。但高階組件本身并不是React API。它只是一種模式,這種模式是由React自身的組合性質(zhì)必然產(chǎn)生的。
高階函數(shù)
說到高階組件,就先得說到高階函數(shù)了,高階函數(shù)是至少滿足下列條件的函數(shù):
1、接受一個(gè)或多個(gè)函數(shù)作為輸入
2、輸出一個(gè)函數(shù)
在javascript這門函數(shù)為一等公民的語(yǔ)言中,高階函數(shù)的使用還是非常之多的,像我們平時(shí)的回調(diào)函數(shù)等等,都用到了高階函數(shù)的知識(shí)。我們先來看一個(gè)簡(jiǎn)單的高階函數(shù)
var fun = function(x, y) { return x + y; }
fun是一個(gè)函數(shù),下面我們將整個(gè)函數(shù)作為參數(shù)傳遞給另一個(gè)函數(shù)
var comp = function(x, y, f) { return f(x,y); }
驗(yàn)證一下
comp(1,2,fun) // 3
高階組件定義
類比高階函數(shù)的定義,高階組件就是接受一個(gè)組件作為參數(shù),在函數(shù)中對(duì)組件做一系列的處理,隨后返回一個(gè)新的組件作為返回值。
我們先定義一個(gè)高階組件BaseActivity
const BaseActivity = (WrappedComponent) => { return class extends Component { render() { return ( <section> <div>我的包裹組件</div> <WrappedComponent /> </section> ) } } }
組件接受一個(gè)被包裹的組件作為參數(shù),返回了一個(gè)經(jīng)過處理的匿名組件。
在其他組件中使用這個(gè)高階組件
class Example extends React.PureComponent { constructor(props) { super(props); this.state = { width: '100%', height: '100%' } } 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: '375px', height: '640px' }) } } render() { let { width, height } = this.state; return ( <div className="activity"> <div className="activity-content" style={{ width, height }}> <button className="btn">參加活動(dòng)</button> </div> </div> ) } } export default BaseActivity(Example);
具體用法就是在export 組件的時(shí)候,使用BaseActivity函數(shù)來包裹這個(gè)組件,看下輸出的react dom內(nèi)容
在Example組件外面包裹了一個(gè)匿名組件。
參數(shù)
既然高階組件是一個(gè)函數(shù),我們就可以向里面?zhèn)鬟f我們需要的參數(shù)
const BaseActivity = (WrappedComponent, title) => { return class extends Component { render() { return ( <section> <div>{title}</div> <WrappedComponent /> </section> ) } } }
在Example中這樣export
export default BaseActivity(Example, '這是高階組件的參數(shù)');
我們看下輸出的react dom
可以看到參數(shù)已經(jīng)傳遞進(jìn)去了。
當(dāng)然還可以這樣用(柯里化)
const BaseActivity (title) => (WrappedComponent) => { return class extends Component { render() { return ( <section> <div>{title}</div> <WrappedComponent /> </section> ) } } }
在Example中這樣export
export default BaseActivity('這是高階組件的參數(shù)')(Example);
這種用法在ant-design的表單以及redux的connect中我們都可以看到
// ant const WrappedDemo = Form.create()(Demo) // redux export default connect(mapStateToProps, mapDispatchToProps)(Counter)
高階組件還可以擴(kuò)展原組件的props屬性,如下所示:
const BaseActivity (title) => (WrappedComponent) => { return class extends Component { render() { const newProps = { id: Math.random().toString(8) } return ( <section> <div>{title}</div> <WrappedComponent {...this.props} {...newProps}/> </section> ) } } }
看下輸出的react dom
高階組件的缺點(diǎn)
高階組件也有一系列的缺點(diǎn),首先是被包裹組件的靜態(tài)方法會(huì)消失,這其實(shí)也是很好理解的,我們將組件當(dāng)做參數(shù)傳入函數(shù)中,返回的已經(jīng)不是原來的組件,而是一個(gè)新的組件,原來的靜態(tài)方法自然就不存在了。如果需要保留,我們可以手動(dòng)將原組件的方法拷貝給新的組件,或者使用hoist-non-react-statics之類的庫(kù)來進(jìn)行拷貝。
結(jié)語(yǔ)
高階函數(shù)對(duì)于初學(xué)者來說可能不太好理解,但當(dāng)你深入其中,了解其中的原理之后,我們可以使用高階函數(shù)來完成很多的工作。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
分享名稱:淺談React高階組件
新聞來源:http://aaarwkj.com/article32/ispcpc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、電子商務(wù)、企業(yè)網(wǎng)站制作、、軟件開發(fā)、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
營(yíng)銷型網(wǎng)站建設(shè)知識(shí)