【譯】展現型組件和容器型組件(做者:Dan Abramov,Redux的開發者)

本文譯自Presentational and Container Components,文章的做者是Dan Abramov,他同時也是Redux和Create React App的做者。 在實際使用React + Redux 技術棧的開發過程當中,很是好的理解了容器型組件和展現型組件的概念是開發出易維護,可複用React App的基礎html

在開發React應用的時候,我發現了一種極其簡單的開發模式。若是你已經用過一段時間的React,你也許已經發現了它。這篇文章已經講的很好了,可是我想補充幾點。react

若是你將組件分爲兩類,你會發現它們更容易被複用和理解。我把這兩類稱爲容器型組件展現型組件 ,可是我也據說過其餘名字,好比臃腫型組件簡單型組件智能型組件傻瓜型組件有狀態組件純組件封裝型組件元組件等等。它們不徹底相同,可是在覈心觀點上是類似的。git

展現型組件github

  • 關心數據的展現方式
  • 內部可能包含展現型組件和容器型組件,而且一般存在其餘DOM元素及其樣式
  • 容許經過this.props.children控制組件
  • 不依賴app中的其它文件,像Flux的actions或stores
  • 不關心數據是如何加載和變化的
  • 僅經過props接收數據和回調函數
  • 幾乎不用組件內的state(若是用到的話,也僅僅是維護UI狀態而不是數據狀態)
  • 除非須要用到state,生命週期函數或性能優化,一般寫成函數式組件
  • 例如:Page,Sidebar,Story,UserInfo,List

容器型組件web

  • 關心數據的運做方式
  • 內部可能包含展現型組件和容器型組件,可是一般沒有任何用於自身的DOM元素,除了一些用於包裹元素的div標籤,而且不存在樣式
  • 爲展現型組件和容器型組件提供數據和操做數據的方法
  • 調用Flux actions並以回調函數的方式給展現型組件提供actions
  • 一般是有狀態的,而且做爲數據源存在
  • 一般由高階函數生成例如React Redux的connect(),Realy的createContainer,或者Flux Utils的Container.create(),而不是手寫的
  • 例如:UserPage,FollowersSidebar,StoryContainer,FollowedUserList

爲了清晰的區分這兩種組件,我把放在不一樣的文件夾中redux

這種方法的優點

  • 關注點分離。經過用這種方式開發組件,你能夠更好的理解你的app和UI
  • 更好的複用性。你能夠在不一樣的數據源中使用相同的展現型組件,也能夠把它們放進不一樣容器型組件中更進一步的進行復用
  • 展現型組件是你的app必不可少的"調色板",你能夠把它們放在一個獨立的頁面中,讓設計師隨意拖拽它們的變量而不改變應用的邏輯。在這個頁面上進行頁面快照迴歸測試
  • 這種方法逼你去把用於佈局的組件抽出來,例如SidebarPageContextMenu。而後經過子組件的方式引入而不是在各個容器型組件中複製粘貼已有的樣式和佈局

記住,組件不必定要輸出DOM元素,它們只須要提供UI之間的組合關係和分界數組

好好利用這一點性能優化

何時引入容器?

我建議你先用展現型組件搭建你的app。最終你會意識到你給中間的組件傳遞了太多的props。有些組件並不使用這些props,而僅僅向下傳遞。而且當下層組件須要更多數據的時候,你必須重寫改寫全部的中間組件。這時候就須要引入一些容器型組件。經過這種方式,你能夠從葉子節點組件獲取數據和方法,而不用考慮處於中間的組件。app

這須要邊開發邊重構,因此沒有必要一次作對。隨着平常應用這種模式,你會組件培養出一種『這時候我該抽出一個Container』的直接,就像你已經知道何時應該提取出一個函數同樣。個人Redux教程可能也會幫你一把less

其餘的二分法

展現型組件和容器型組件這種分類並不是十分嚴格,這是按照它們的目的進行分類。

爲了與以前的概念作比較,這是一些相關但不一樣的二分法

  • 有狀態和無狀態 有些組件使用React的setState()方法,有些不用。容器型組件每每是有狀態的而展現型組件每每是無狀態的,這並非一條鐵律。展現型組件也能夠是有狀態的,容器型組件也能夠是無狀態的
  • 類和函數 從React0.14開始,組件既能夠聲明爲類也能夠聲明爲函數。函數式組件能夠定義的更簡單可是也缺乏一些只能在類組件中使用的特寫。有些限制可能將來會消除,可是在當下仍然是存在的。因爲函數式組件更加易於理解,因此我建議你儘可能的使用它。除非你須要state,生命週期函數,或者性能優化,這些特性只有在類組件中才可使用。
  • 純和非純 若是一個組件在輸入相同props的狀況下老是輸出相同的結果,那咱們稱這個組件爲pure component。pure component既能夠聲明爲類組件也能夠聲明爲函數式組件,便可以是有狀態的也能夠是無狀態的。另外一個重要的方面是,pure component不依賴propsstate的深層比對,因此能夠在shouldComponentUpdate方法中進行淺比較優化性能,可是在將來可能有不少變化。

展現型組件和容器型組件均可以放進以上任何一種二分法中。在我看來,展現型組件每每是無狀態的純函數組件,容器型組件每每是有狀態的純類組件。然而這並非一種要求,而是一種現象,而且在一些特定的場景中我也確實見過徹底相反的狀況。

不要把展現型組件和容器型組件的劃分當成教條。有的時候沒有必要對兩者進行區分。若是你不太肯定一個組件是展現型組件仍是容器型組件,也許如今還不是區分它的時候,別太心急!

例子

Michael Chan爲咱們用一個gist闡釋了上面的道理

延伸閱讀

相關文章
相關標籤/搜索