談?wù)凴eact中的Render Props模式
概述
Render Props模式是一種非常靈活復(fù)用性非常高的模式,它可以把特定行為或功能封裝成一個(gè)組件,提供給其他組件使用讓其他組件擁有這樣的能力,接下來(lái)我們一步一步來(lái)看React組件中如何實(shí)現(xiàn)這樣的功能。
簡(jiǎn)要介紹:分離UI與業(yè)務(wù)的方法一直在演進(jìn),從早期的mixins,到HOC,再到Render Prop,本文主要對(duì)比HOC,談?wù)凴ender Props
1 . 早期的mixins
早期復(fù)用業(yè)務(wù)通過(guò)mixins來(lái)實(shí)現(xiàn),比如組件A和組件B中,有一些公用函數(shù),通過(guò)mixins剝離這些公用部分,并將其組合成一個(gè)公用集合,然后將這個(gè)集合傳遞給每個(gè)組件調(diào)用。
//公有的函數(shù)部分
const someMixins={
printColor(){
console.log(this.state.color);
}
printWeight(){
console.log(this.state.weight);
}
}
class Apple extends React.Component{
//僅僅作為演示,mixins一般是通過(guò)React.createClass創(chuàng)建,并且ES6也沒(méi)有key:value這種寫(xiě)法
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}>
這是一個(gè)蘋(píng)果
</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}>
這是一個(gè)香蕉
</div>
}
}
上述的例子中,Apple和Banana都具有printColor和printWeight方法,通過(guò)mixins分離公共業(yè)務(wù)。mixins已經(jīng)在React16.0版本移除,這里僅僅做一個(gè)介紹。
2 . HOC
HOC簡(jiǎn)單理解就是組件工廠,接受原始組件作為參數(shù),添加完功能與業(yè)務(wù)后,返回新的組件。下面來(lái)介紹HOC參數(shù)的幾個(gè)例子。
(1)參數(shù)僅為原始組件,比如:
const redApple = withFruit(Apple);
(2)參數(shù)為原始組件和一個(gè)對(duì)象,比如:
const redApple = withFruit(Apple,{color:'red',weight:'200g'});
但是這種情況比較少用,如果對(duì)象中僅僅傳遞的是屬性,其實(shí)完全可以通過(guò)組件的props實(shí)現(xiàn)值的傳遞,我們用HOC的主要目的是分離業(yè)務(wù),關(guān)于UI的展示,以及一些組件中的屬性和狀態(tài),我們一般通過(guò)props來(lái)指定比較方便
(3)參數(shù)為原始組件和一個(gè)函數(shù),比如:
const redApp=withFruit(App,()=>{console.log('I am a fruit')})
這種是HOC的典型例子,原始組件參數(shù)表示UI部分,函數(shù)參數(shù)表示處理邏輯,在HOC工廠中進(jìn)行耦合后生成新的組件。
(4)柯里化
最常見(jiàn)的是僅以一個(gè)原始組件作為參數(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的缺點(diǎn)
下面我們來(lái)看看HOC的缺點(diǎn):
(1)難以溯源,且存在屬性覆蓋問(wèn)題
如果原始組件A,先后通過(guò)工廠函數(shù)1,工廠函數(shù)2,工廠函數(shù)3….構(gòu)造,最后生成了組件B,我們知道組件B中有很多與A組件不同的props,但是我們僅僅通過(guò)組件B,并不能知道哪個(gè)組件來(lái)自于哪個(gè)工廠函數(shù)。同時(shí),如果有2個(gè)工廠函數(shù)同時(shí)修改了組件A的某個(gè)同名屬性,那么會(huì)有屬性覆蓋的問(wèn)題,會(huì)使得前一個(gè)工廠函數(shù)的修改結(jié)果失效。
(2)HOC是靜態(tài)構(gòu)建的
所謂靜態(tài)構(gòu)建,也就是說(shuō)生成的是一個(gè)新的組件,并不會(huì)馬上render,HOC組件工廠是靜態(tài)構(gòu)建一個(gè)組件,這類(lèi)似于重新聲明一個(gè)組件的部分。也就是說(shuō),HOC工廠函數(shù)里面的聲明周期函數(shù),也只有在新組件被渲染的時(shí)候才會(huì)執(zhí)行。
(3)會(huì)產(chǎn)生無(wú)用的空組件
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>
<h1>Move the mouse around!</h1>
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</div>
);
}
}
上述是官網(wǎng)給出的例子,我們來(lái)看主要是部分是下面這兩句:
Class Mouse extends React.component{
...
{this.props.render(this.state)}
...
}
......
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
在使用Mouse組件的時(shí)候,通過(guò)一個(gè)render屬性,傳遞一個(gè)可用組件Cat給父組件Mouse,而在Mouse組件中,可以將本身的state對(duì)象傳遞給Cat組件,Cat組件中的mouse屬性的值與Mouse父組件中的state相同。
精簡(jiǎn)來(lái)說(shuō): 就是父組件可以將自己的state傳遞給子組件,而子組件可以根據(jù)父組件的state對(duì)象,來(lái)進(jìn)行render。
這樣做的好處是:
(1)不用擔(dān)心props的命名問(wèn)題
(2)可以溯源,子組件的props一定是來(lái)自于直接父組件
(3)是動(dòng)態(tài)構(gòu)建的。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
淺談React-router v6 實(shí)現(xiàn)登錄驗(yàn)證流程
本文主要介紹了React-router v6 實(shí)現(xiàn)登錄驗(yàn)證流程,主要介紹了公共頁(yè)面、受保護(hù)頁(yè)面和登錄頁(yè)面,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
詳解vant2 自動(dòng)檢查表單驗(yàn)證 -validate
這篇文章主要介紹了vant2 自動(dòng)檢查表單驗(yàn)證 -validate,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
詳解在React.js中使用PureComponent的重要性和使用方式
這篇文章主要介紹了詳解在React.js中使用PureComponent的重要性和使用方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
詳解如何用webpack4從零開(kāi)始構(gòu)建react開(kāi)發(fā)環(huán)境
這篇文章主要介紹了詳解如何用webpack4從零開(kāi)始構(gòu)建react開(kāi)發(fā)環(huán)境,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
如何用webpack4.0擼單頁(yè)/多頁(yè)腳手架 (jquery, react, vue, typescript)
這篇文章主要介紹了如何用webpack4.0擼單頁(yè)/多頁(yè)腳手架 (jquery, react, vue, typescript),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
React中 Zustand狀態(tài)管理庫(kù)的使用詳解
Zustand?是一個(gè)非常輕量、簡(jiǎn)潔的狀態(tài)管理庫(kù),旨在為 React 提供簡(jiǎn)便且高效的狀態(tài)管理,相比于 Redux 或 Context API,Zustand 具有更簡(jiǎn)潔、靈活和易于理解的優(yōu)點(diǎn),感興趣的朋友一起看看吧2024-12-12
一文詳解如何使用React監(jiān)聽(tīng)網(wǎng)絡(luò)狀態(tài)
在現(xiàn)代Web應(yīng)用程序中,網(wǎng)絡(luò)連接是至關(guān)重要的,通過(guò)監(jiān)聽(tīng)網(wǎng)絡(luò)狀態(tài),我們可以為用戶(hù)提供更好的體驗(yàn),例如在斷網(wǎng)時(shí)顯示有關(guān)網(wǎng)絡(luò)狀態(tài)的信息,本文將介紹如何使用React監(jiān)聽(tīng)網(wǎng)絡(luò)狀態(tài)的變化,并提供相應(yīng)的代碼示例2023-06-06
react?Scheduler?實(shí)現(xiàn)示例教程
這篇文章主要為大家介紹了react?Scheduler?實(shí)現(xiàn)示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

