uniapp 子组件 props拿不到数据_总结下React组件间的通讯
隨著組件化開(kāi)發(fā)成為主流,每個(gè)組件都有完善的生命周期,大家可以在生命周期內(nèi)做一些事情,每個(gè)組件有自己的狀態(tài)管理機(jī)制。同時(shí),每個(gè)組件都是獨(dú)立的。這能提高大家的開(kāi)發(fā)效率,規(guī)范化開(kāi)發(fā)。
今天,想整理下每個(gè)獨(dú)立組件間如何通訊呢?這很關(guān)鍵,關(guān)鍵到每次開(kāi)發(fā)中都會(huì)遇到,習(xí)以為常了。
我想我可以根據(jù)下面4點(diǎn)進(jìn)入話題。
如果,你看到了這篇文章。那么,能有你的反饋就更棒了。
一:組件間存在哪些關(guān)系形式呢?
我們知道,在標(biāo)準(zhǔn)網(wǎng)頁(yè)中,組織頁(yè)面文檔的對(duì)象被組織在一個(gè)樹(shù)形結(jié)構(gòu)。
同樣,在React中,各個(gè)組件也是被組織在一個(gè)樹(shù)形結(jié)構(gòu)中。平時(shí)寫(xiě)慣了JSX,不會(huì)在意這種關(guān)系,JSX 最終的會(huì)被編譯成React.createElement( type, [props], [...children] ),更能明顯的發(fā)現(xiàn)這種關(guān)系。比如:
<會(huì)被編譯為以下(這也是,為什么即便我們寫(xiě)React函數(shù)式組件,也需要引入React,不然會(huì)報(bào)import ‘react’錯(cuò)誤的原因)
React所以,React組件間存在的關(guān)系呢,可以想象以下一個(gè)樹(shù)形結(jié)構(gòu)各個(gè)節(jié)點(diǎn)存在的關(guān)系。
畫(huà)了一張粗劣的樹(shù)形結(jié)構(gòu)組件間大概存在的關(guān)系是:
- 父子關(guān)系(子父關(guān)系),如:<Root>與<ParentA>
- 兄弟關(guān)系,如:<ParentA>與<ParentB>
- '沒(méi)有'關(guān)系(因?yàn)楦袅颂嗉?jí),忽略為沒(méi)有關(guān)系),如<ParentA>與<Son1_1>,<ChildA1>與<ChildB1>
然后組件有哪些通訊需求呢?
- 父組件向子組件通訊
- 子組件向父組件通訊
- 兄弟組件間的通訊
- 沒(méi)有關(guān)系的組件間的通訊,比如‘群發(fā)’
現(xiàn)在我們分析存在的通訊需求,下面我們先來(lái)看看有哪些通訊'手段'方式。
二:常用的通訊'手段'方式有哪些呢?
a.通過(guò)props傳遞參數(shù),進(jìn)行通訊
在react中,數(shù)據(jù)流是單向流動(dòng) (自上層往下層流動(dòng)) 的,數(shù)據(jù)通過(guò)props從父組件傳遞到子組件,子組件可以通過(guò)props獲取父組件傳遞過(guò)來(lái)的數(shù)據(jù)。
上面我們提到每個(gè)組件都有獨(dú)立的聲明周期、狀態(tài)管理。我們可以利用這些特色,完成父組件到子組件的通訊。當(dāng)父組件需要通知子組件時(shí),通過(guò)setState觸發(fā)狀態(tài)變化,傳遞props,完成通訊。下面展示的是單級(jí)的情況,多級(jí)的情況是一樣的,在Child中引入其他組件,給它傳遞props,參數(shù)很多的情況,可以利用ES6的...運(yùn)算符進(jìn)行結(jié)構(gòu),如:{...this.props},代碼如下:
classb.通過(guò)調(diào)用props傳遞function,進(jìn)行通訊
如果子組件需要向父組件通訊呢?我們知道props可以傳遞多種數(shù)據(jù)類型(number、bool、object、string、func等)。
因此,父組件可以通過(guò)props給子組件傳遞func類型的參數(shù),子組件內(nèi)通過(guò)調(diào)用這個(gè)func類型的參數(shù),完成通訊,代碼如下:
classc.通過(guò)ref獲取組件實(shí)例,調(diào)用實(shí)例方法進(jìn)行通訊
注:React推崇的是通過(guò)數(shù)據(jù)流,來(lái)完成組件間的通訊,更多情況下,我們都可以通過(guò)props數(shù)據(jù)完成需求。這里只是提供一種思路,大家不要濫用如果我們能獲取到一個(gè)組件的實(shí)例,那就意味著我們可以調(diào)用這個(gè)實(shí)例內(nèi)的方法,完成組件間通訊。React給我們提供獲取組件實(shí)例的方法ref。
這種方式適用于哪些使用場(chǎng)景?
我想可以舉1、Toast類型的組件中的應(yīng)用;2、高階組件中的應(yīng)用
都在項(xiàng)目中都用過(guò)Toast這種類型的組件,這種組件的特點(diǎn)是:
- 用得非常頻繁,可能多次調(diào)用。
- 在各種不同的組件上都有可能用到
- 需求比較穩(wěn)定,穩(wěn)定到我們可以預(yù)知(成功、失敗、提醒、信息)
因?yàn)檎{(diào)用頻繁,從性能方面考慮,我們需要它只創(chuàng)建一次,不要重復(fù)的創(chuàng)建。
因?yàn)樵诓煌M件內(nèi)用到,所以我們希望不用在不同的組件內(nèi)進(jìn)行寫(xiě)入組件,可以用最簡(jiǎn)單的方式調(diào)用。結(jié)合需求,我們希望用這樣的形式調(diào)用。比如這樣:Toast.success('成功了');、Toast.error('失敗了');、Toast.tip('登錄超時(shí)了');
如果,讓你做個(gè)Toast組件你會(huì)怎么做呢?
我是通過(guò)ref獲取Toast組件實(shí)例,通過(guò)實(shí)例操作Toast組件內(nèi)的信息隊(duì)列,來(lái)實(shí)現(xiàn)。一下是github源碼地址,有興趣的可以了解下。當(dāng)然也有其他方式。歡迎大家評(píng)論(請(qǐng)輕噴)哈。
Toast組件演示,有代碼注釋。
以下代碼簡(jiǎn)單演示下通過(guò)ref通訊
class以下是高階組件中的應(yīng)用。
大家都用過(guò)類似“onClickOutside”這樣的高階組件。高階組件,由于通用性較高,因此,往往需要在高階組件內(nèi)直接調(diào)用WappedComponent內(nèi)部的方法,因此,需要通過(guò)用ref獲取WappedComponent組件實(shí)例,在通過(guò)實(shí)例調(diào)用內(nèi)部的方法。
案例的話可以去git上看下onClickOutside的源碼。
d.通過(guò)回調(diào)函數(shù)方法進(jìn)行通訊
在b方案中,我們知道可以通過(guò)子組件調(diào)用props傳遞的方法完成通訊。
在此基礎(chǔ)上,我們引入一個(gè)需求,需要在父組件的方法被調(diào)用后,告訴子組件調(diào)用完成。來(lái)完成Child ->Parent->Child這樣的通訊。
當(dāng)然我們可以通過(guò)結(jié)合a、b兩種方案來(lái)完成需求,在Parent組件中存儲(chǔ)一個(gè)狀態(tài),代表Child組件完成了調(diào)用。
但是,有時(shí)候,我們不希望在Parent組件中維護(hù)這樣的一個(gè)狀態(tài),這個(gè)時(shí)候我們就可以通過(guò)回調(diào)方法的方式完成這種需求。提供我寫(xiě)的一個(gè)panel組件的一個(gè)案例,在窗口關(guān)閉前,需要讓父組件完成退出動(dòng)畫(huà),在退出動(dòng)畫(huà)完成后,在通知panel組件可以隱藏關(guān)閉按鈕,而后關(guān)閉了。歡迎大家評(píng)論(請(qǐng)輕噴)哈。github地址:
一個(gè)動(dòng)畫(huà)面板組件,用了回調(diào)方法
以下代碼簡(jiǎn)單演示下通過(guò)回調(diào)函數(shù)方法進(jìn)行通訊
classe.觀察者模式,添加訂閱,發(fā)布通知的方式進(jìn)行通訊
假設(shè)兩個(gè)組件間'沒(méi)有關(guān)系',如果我們想通過(guò)props進(jìn)行通訊,那么會(huì)造成兩個(gè)問(wèn)題
- 參數(shù)需要跨多層級(jí)的傳遞
- 數(shù)據(jù)需要走到共同的父組件,完成setState狀態(tài)更新,再創(chuàng)給子組件。會(huì)造成共同的組件邏輯會(huì)混亂,setState后,所有的子組件都會(huì)'更新',造成浪費(fèi)(雖然你可以用PureComponent、或者shouldComponentUpdate優(yōu)化不必要的性能浪費(fèi))
這個(gè)時(shí)候,我們可以考慮封裝一個(gè)簡(jiǎn)潔的觀察者模式(訂閱與通知)。通訊目標(biāo)組件添加通知訂閱,在通訊源組件調(diào)用通知。
這樣通知的時(shí)候只會(huì)更新添加了對(duì)應(yīng)訂閱的組件,其他組件不會(huì)影響。不同的組件也可以添加同一個(gè)訂閱,完成所謂的群發(fā)。
github地址,大家可以參考下。
一個(gè)簡(jiǎn)單的觀察者模式,代碼有注釋
以下用代碼簡(jiǎn)單展示下,具體代碼可以看github地址:
// 簡(jiǎn)易的觀察者模式f.引入Redux等
在業(yè)務(wù)比較復(fù)雜的代碼中大家可以引入Redux來(lái)管理我們的數(shù)據(jù),Redux分兩部分redux和react-redux。
react-redux相對(duì)好理解一些,提供Provider和Connect兩個(gè)高階組件。Provider確保Children.only;Connect 實(shí)現(xiàn)stateToProps、dispatchToProps,同時(shí)在componentDidMount時(shí)添加訂閱,在componentWillUnmout時(shí)移除訂閱。
而,redux提供非常經(jīng)典。提供了reducer、dispatch、subscribe、applyMiddleware的整條方案。這部分要深入的話可以寫(xiě)很多,有機(jī)會(huì)再寫(xiě)一篇來(lái)深入講講源碼。
三:擴(kuò)展
到這里也差不多了。
大概分享了下組件間的關(guān)系。
- 父子關(guān)系(子父關(guān)系),如:<Root>與<ParentA>
- 兄弟關(guān)系,如:<ParentA>與<ParentB>
- '沒(méi)有'關(guān)系(因?yàn)楦袅颂嗉?jí),忽略為沒(méi)有關(guān)系)
組件間的通訊方式。
- 通過(guò)props傳遞參數(shù),進(jìn)行通訊
- 通過(guò)調(diào)用props傳遞function,進(jìn)行通訊
- 通過(guò)ref獲取組件實(shí)例,調(diào)用實(shí)例方法進(jìn)行通訊
- 通過(guò)回調(diào)函數(shù)方法進(jìn)行通訊
- 觀察者模式,添加訂閱,發(fā)布通知的方式進(jìn)行通訊
- 引入Redux等
同時(shí),如果可以用props數(shù)據(jù)流的方式實(shí)現(xiàn)的盡量用props數(shù)據(jù)流的方式進(jìn)行。展示了一些代碼,然后一個(gè)組件庫(kù),會(huì)慢慢完善,出一套對(duì)應(yīng)的移動(dòng)版,還沒(méi)有發(fā)布npm。
一些React組件?coocssweb.github.io如果能有你的反饋那就太好了。如果能有你的反饋那就太好了。
如果,大家有其他的方式,可以評(píng)論。或者這些方式有哪些不合理,也可以輕噴。
One More Thing
嗯哼?封面是手畫(huà)的,就那很丑的那張,我畫(huà)的。
這個(gè)也請(qǐng)輕噴。
總結(jié)
以上是生活随笔為你收集整理的uniapp 子组件 props拿不到数据_总结下React组件间的通讯的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java怎么给类中的私有变量赋值_Jav
- 下一篇: 如何判断数组所有数都不等于一个数_【每日