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