您好,登錄后才能下訂單哦!
這篇文章主要介紹React中Render Props模式有什么用,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!
概述
Render Props模式是一種非常靈活復(fù)用性非常高的模式,它可以把特定行為或功能封裝成一個組件,提供給其他組件使用讓其他組件擁有這樣的能力,接下來我們一步一步來看React組件中如何實現(xiàn)這樣的功能。
簡要介紹:分離UI與業(yè)務(wù)的方法一直在演進(jìn),從早期的mixins,到HOC,再到Render Prop,本文主要對比HOC,談?wù)凴ender Props
1 . 早期的mixins
早期復(fù)用業(yè)務(wù)通過mixins來實現(xiàn),比如組件A和組件B中,有一些公用函數(shù),通過mixins剝離這些公用部分,并將其組合成一個公用集合,然后將這個集合傳遞給每個組件調(diào)用。
//公有的函數(shù)部分 const someMixins={ printColor(){ console.log(this.state.color); } printWeight(){ console.log(this.state.weight); } } class Apple extends React.Component{ //僅僅作為演示,mixins一般是通過React.createClass創(chuàng)建,并且ES6也沒有key:value這種寫法 mixins:[someMixins] constructor(props){ super(props); this.state={ color:'red', weight:'100g' } this.printColor=this.printColor.bind(this); } render(){ return <div className="m-box" onClick={this.printColor}> 這是一個蘋果 </div> } } class Banana extends React.Component{ mixins:[someMixins] constructor(props){ super(props); this.state={ color:'yellow', weight:'200g' } this.printColor=this.printColor.bind(this); } render(){ return <div className="m-box" onClick={this.printColor}> 這是一個香蕉 </div> } }
上述的例子中,Apple和Banana都具有printColor和printWeight方法,通過mixins分離公共業(yè)務(wù)。mixins已經(jīng)在React16.0版本移除,這里僅僅做一個介紹。
2 . HOC
HOC簡單理解就是組件工廠,接受原始組件作為參數(shù),添加完功能與業(yè)務(wù)后,返回新的組件。下面來介紹HOC參數(shù)的幾個例子。
(1)參數(shù)僅為原始組件,比如:
const redApple = withFruit(Apple);
(2)參數(shù)為原始組件和一個對象,比如:
const redApple = withFruit(Apple,{color:'red',weight:'200g'});
但是這種情況比較少用,如果對象中僅僅傳遞的是屬性,其實完全可以通過組件的props實現(xiàn)值的傳遞,我們用HOC的主要目的是分離業(yè)務(wù),關(guān)于UI的展示,以及一些組件中的屬性和狀態(tài),我們一般通過props來指定比較方便
(3)參數(shù)為原始組件和一個函數(shù),比如:
const redApp=withFruit(App,()=>{console.log('I am a fruit')})
這種是HOC的典型例子,原始組件參數(shù)表示UI部分,函數(shù)參數(shù)表示處理邏輯,在HOC工廠中進(jìn)行耦合后生成新的組件。
(4)柯里化
最常見的是僅以一個原始組件作為參數(shù),但是在外層包裹了業(yè)務(wù)邏輯,比如react-redux的conect函數(shù)中:
class Admin extends React.Component{ } const mapStateToProps=(state)=>{ return { }; } const mapDispatchToProps=(dispatch)=>{ return { } } const connect(mapStateToProps,mapDispatchToProps)(Admin)
這里不是嚴(yán)格的柯里化,但是思想是一樣的,在HOC的工廠函數(shù)中在包一層父函數(shù),用于指定業(yè)務(wù)邏輯。
3 . HOC的缺點
下面我們來看看HOC的缺點:
(1)難以溯源,且存在屬性覆蓋問題
如果原始組件A,先后通過工廠函數(shù)1,工廠函數(shù)2,工廠函數(shù)3….構(gòu)造,最后生成了組件B,我們知道組件B中有很多與A組件不同的props,但是我們僅僅通過組件B,并不能知道哪個組件來自于哪個工廠函數(shù)。同時,如果有2個工廠函數(shù)同時修改了組件A的某個同名屬性,那么會有屬性覆蓋的問題,會使得前一個工廠函數(shù)的修改結(jié)果失效。
(2)HOC是靜態(tài)構(gòu)建的
所謂靜態(tài)構(gòu)建,也就是說生成的是一個新的組件,并不會馬上render,HOC組件工廠是靜態(tài)構(gòu)建一個組件,這類似于重新聲明一個組件的部分。也就是說,HOC工廠函數(shù)里面的聲明周期函數(shù),也只有在新組件被渲染的時候才會執(zhí)行。
(3)會產(chǎn)生無用的空組件
4. render props
class Cat extends React.Component { render() { const mouse = this.props.mouse; return ( <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} /> ); } } class Mouse extends React.Component { constructor(props) { super(props); this.handleMouseMove = this.handleMouseMove.bind(this); this.state = { x: 0, y: 0 }; } handleMouseMove(event) { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}> {/* Instead of providing a static representation of what <Mouse> renders, use the `render` prop to dynamically determine what to render. */} {this.props.render(this.state)} </div> ); } } class MouseTracker extends React.Component { render() { return ( <div> <h2>Move the mouse around!</h2> <Mouse render={mouse => ( <Cat mouse={mouse} /> )}/> </div> ); } }
上述是官網(wǎng)給出的例子,我們來看主要是部分是下面這兩句:
Class Mouse extends React.component{ ... {this.props.render(this.state)} ... } ...... <Mouse render={mouse => ( <Cat mouse={mouse} /> )}/>
在使用Mouse組件的時候,通過一個render屬性,傳遞一個可用組件Cat給父組件Mouse,而在Mouse組件中,可以將本身的state對象傳遞給Cat組件,Cat組件中的mouse屬性的值與Mouse父組件中的state相同。
精簡來說: 就是父組件可以將自己的state傳遞給子組件,而子組件可以根據(jù)父組件的state對象,來進(jìn)行render。
這樣做的好處是:
(1)不用擔(dān)心props的命名問題
(2)可以溯源,子組件的props一定是來自于直接父組件
(3)是動態(tài)構(gòu)建的。
以上是“React中Render Props模式有什么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。