- 深入理解React Router:從原理到實踐
- 李楊韜
- 996字
- 2021-04-16 16:10:49
3.1 Context
在React中,父組件通常將數(shù)據(jù)作為props傳遞給子組件。如果需要跨層級傳遞數(shù)據(jù),那么使用props逐層傳遞數(shù)據(jù)將會使開發(fā)變得復雜。同時,在實際開發(fā)中,許多組件需要一些相同的東西,如國際化語言配置、應用的主題色等,在開發(fā)組件的過程中也不希望逐級傳遞這些配置信息。
在這種情況下,可以使用React的Context特性。Context被翻譯為上下文,如同字面意思,其包含了跨越當前層級的信息。
Context在許多組件或者開發(fā)庫中有著廣泛的應用,如react-redux使用Context作為Provider,提供全局的store,以及React Router通過Context提供路由狀態(tài)。掌握Context將會對理解React Router起到極大的幫助作用。這里以圖3-1來說明Context如何跨組件傳遞數(shù)據(jù)。
在圖3-1中,左側(cè)組件樹使用了逐層傳遞props的方式來傳遞數(shù)據(jù),即使組件B、組件C不需要關心某個數(shù)據(jù)項,也被迫需要將該數(shù)據(jù)項作為props傳遞給子組件。而使用Context來實現(xiàn)組件間跨層級的數(shù)據(jù)傳遞,數(shù)據(jù)可直接從組件A傳遞到組件D中。

圖3-1 Context跨組件傳遞數(shù)據(jù)
在React v16.3及以上版本中,可使用React.createContext接口創(chuàng)建Context容器。基于生產(chǎn)者-消費者模式,創(chuàng)建容器后可使用容器提供方(一般稱為Provider)提供某跨層級數(shù)據(jù),同時使用容器消費方(一般稱為Consumer)消費容器提供方所提供的數(shù)據(jù)。示例如下:


通過setState改變count的值,觸發(fā)render渲染,Context.Provider會將最新的value值傳遞給所有的Context.Consumer。

在上例中,頂層組件App使用 CountContext.Provider將this.state.count的值提供給后代組件。App的子組件Toolbar不消費Provider所提供的數(shù)據(jù),Toolbar的子組件Button使用CountContext.Consumer獲得App所提供的數(shù)據(jù)count。中間層的Toolbar組件對數(shù)據(jù)跨層級傳遞沒有任何感知。在單擊“更新”按鈕觸發(fā)數(shù)據(jù)傳遞時,Toolbar中的“Toolbar render”信息不會被打印。每次單擊“更新”按鈕時,僅會打印“app render”與“Button render”,這是因為在Provider所提供的值改變時,僅Consumer會渲染,所以Toolbar中的“Toolbar render”不會被打印。
如果在Toolbar中也使用Provider提供數(shù)據(jù),如提供的value為500:

則Button中的Consumer得到的值將為500。原因在于當有多個Provider時,Consumer將消費組件樹中最近一級的Provider所提供的值。這作為React的一個重要特性,在React Router源碼中被大量應用。
注意,如果不設置Context.Provider的value,或者傳入undefined,則Consumer并不會獲得創(chuàng)建Context時的defaultValue數(shù)據(jù)。創(chuàng)建Context時的defaultValue數(shù)據(jù)主要提供給沒有匹配到Provider的Consumer,如果去掉App中的Provider,則Consumer所獲得的值為1。
如果希望使用this.context方式獲取Provider所提供的值,則可聲明類的靜態(tài)屬性contextType(React v16.6.0)。contextType的值為創(chuàng)建的Context,如:

在React v16.3以前,不支持通過createContext的方式創(chuàng)建上下文,可使用社區(qū)的polyfill方案,如create-react-context等。
注意,組件的優(yōu)化方法如shouldComponentUpdate或者React.memo不能影響Context值的傳遞。若在Button中引入shouldComponentUpdate,則會阻止Button更新:

改變Provider所提供的值后,依然會觸發(fā)Consumer的重新渲染,結(jié)果與未引入shouldComponentUpdate時一致。
- 微服務與事件驅(qū)動架構(gòu)
- Visual Basic程序設計教程
- Java技術手冊(原書第7版)
- AngularJS深度剖析與最佳實踐
- Data Analysis with IBM SPSS Statistics
- Web Application Development with MEAN
- SSM輕量級框架應用實戰(zhàn)
- Julia for Data Science
- Building Serverless Architectures
- OpenCV 3 Blueprints
- Java程序設計基礎(第6版)
- Learning Concurrency in Python
- Scrapy網(wǎng)絡爬蟲實戰(zhàn)
- Python面試通關寶典
- Android技術內(nèi)幕(系統(tǒng)卷)