本文譯自Presentational and Container Components,文章的做者是Dan Abramov,他同時也是Redux和Create React App的做者。 在實際使用React + Redux 技術棧的開發過程當中,很是好的理解了容器型組件和展現型組件的概念是開發出易維護,可複用React App的基礎html
在開發React應用的時候,我發現了一種極其簡單的開發模式。若是你已經用過一段時間的React,你也許已經發現了它。這篇文章已經講的很好了,可是我想補充幾點。react
若是你將組件分爲兩類,你會發現它們更容易被複用和理解。我把這兩類稱爲容器型組件 和 展現型組件 ,可是我也據說過其餘名字,好比臃腫型組件和簡單型組件,智能型組件和傻瓜型組件,有狀態組件和純組件,封裝型組件和元組件等等。它們不徹底相同,可是在覈心觀點上是類似的。git
展現型組件github
this.props.children
控制組件props
接收數據和回調函數state
(若是用到的話,也僅僅是維護UI狀態而不是數據狀態)state
,生命週期函數或性能優化,一般寫成函數式組件,Page
,Sidebar
,Story
,UserInfo
,List
容器型組件web
div
標籤,而且不存在樣式connect()
,Realy的createContainer
,或者Flux Utils的Container.create()
,而不是手寫的UserPage
,FollowersSidebar
,StoryContainer
,FollowedUserList
爲了清晰的區分這兩種組件,我把放在不一樣的文件夾中redux
Sidebar
,Page
,ContextMenu
。而後經過子組件的方式引入而不是在各個容器型組件中複製粘貼已有的樣式和佈局記住,組件不必定要輸出DOM元素,它們只須要提供UI之間的組合關係和分界數組
好好利用這一點性能優化
我建議你先用展現型組件搭建你的app。最終你會意識到你給中間的組件傳遞了太多的props。有些組件並不使用這些props,而僅僅向下傳遞。而且當下層組件須要更多數據的時候,你必須重寫改寫全部的中間組件。這時候就須要引入一些容器型組件。經過這種方式,你能夠從葉子節點組件獲取數據和方法,而不用考慮處於中間的組件。app
這須要邊開發邊重構,因此沒有必要一次作對。隨着平常應用這種模式,你會組件培養出一種『這時候我該抽出一個Container』的直接,就像你已經知道何時應該提取出一個函數同樣。個人Redux教程可能也會幫你一把less
展現型組件和容器型組件這種分類並不是十分嚴格,這是按照它們的目的進行分類。
爲了與以前的概念作比較,這是一些相關但不一樣的二分法
setState()
方法,有些不用。容器型組件每每是有狀態的而展現型組件每每是無狀態的,這並非一條鐵律。展現型組件也能夠是有狀態的,容器型組件也能夠是無狀態的state
,生命週期函數,或者性能優化,這些特性只有在類組件中才可使用。props
的狀況下老是輸出相同的結果,那咱們稱這個組件爲pure component。pure component既能夠聲明爲類組件也能夠聲明爲函數式組件,便可以是有狀態的也能夠是無狀態的。另外一個重要的方面是,pure component不依賴props
和state
的深層比對,因此能夠在shouldComponentUpdate
方法中進行淺比較優化性能,可是在將來可能有不少變化。展現型組件和容器型組件均可以放進以上任何一種二分法中。在我看來,展現型組件每每是無狀態的純函數組件,容器型組件每每是有狀態的純類組件。然而這並非一種要求,而是一種現象,而且在一些特定的場景中我也確實見過徹底相反的狀況。
不要把展現型組件和容器型組件的劃分當成教條。有的時候沒有必要對兩者進行區分。若是你不太肯定一個組件是展現型組件仍是容器型組件,也許如今還不是區分它的時候,別太心急!
Michael Chan爲咱們用一個gist闡釋了上面的道理