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