譯文《容器元件和展示元件》原作者:Dan Abramov
前言
最初學習react時,只是認識了它的api與十分好用的jsx語法。現在嘗試著用react和meteor寫實際webapp時,就不知不覺地習慣了一些react方法。今晚偶然逛到redux作者——Dan Abramov的medium主頁,發現他的《Presentational and Container Components》文章中總結了一種模式。看後,獲益匪淺,便將其翻譯了,分享給大家。
譯文
容器元件和展示元件
容器元件和展示元件名詞都來自於redux中文文件。
我在用react寫程式時,發現了一種簡單好用的模式。如果你也熟悉react,或許它早就被你發現了。有一篇文章講得很好,但是,我想補充幾點。
如果你將元件分成兩類,你會發現它們容易更被重用和理解。這兩類我稱之為容器元件和展示元件。我也聽過其他說法,比如"臃腫的"和"苗條的","智慧的"和"單調的","多狀態變數"和"單純的","封裝物"和"元件"等等。概念不完全一致,卻有一樣的中心思想。
我所說的展示元件:
- 只關心它們的樣子。
- 可能同時包含子級容器元件和展示元件,一般含DOM標籤和自定的樣式。
- 通常用<code>this.props.children</code>來包含其他元件
- 不依賴app其它元件,比如flux的actions和stores
- 不會定義資料如何讀取,如何改變
- 只通過<code>this.props</code>接受資料和回撥函式
- 很少有自己的狀態變數,即使有,也是UI的狀態變數,比如<code>toggleMenuOpen</code>,<code>InputFocus</code>
- 一般是函式級元件,除非它們需要狀態,lifecycle hooks,優化處理。
lifecycle hook這個詞語很形象,但我不知道怎麼翻譯得貼切-_-!大概指那些監控元件生命週期裡一些關鍵時刻的函式,比如,我需要在這元件初始化的時候呼叫某函式,那麼我實現一個<code>onInit()</code>介面。react中的componentWillMount之類的函式也許也是lifecycle hook?
- 例子有Page,Sidebar,Story,UserInfo,List。
我所說的容器元件
- 只關心它們的運作方式。
- 可能同時包含子級容器元件和展示元件,但大都不含DOM標籤,而含他們自己所用的wrapping div,從不用自己的樣式。
- 為展示元件或其他元件提供資料和方法。
- 呼叫Flux的actions,並且將其作為展示元件的回撥函式。
- 維持許多狀態變數,通常充當一個資料來源。
- 通常由高階元件生成,比如Redux裡的connect(),Relay裡的createContainer(),Flux Utils裡的Container.create(),而非手工寫出(譯者:可能在meteor中資料是例外吧)
- 例子有UserPage, FollowersSidebar, StoryContainer, FollowedUserList。
我把他們放在不同的資料夾中,以示區別。
這種方法的好處
- 分離關注,你可以更好的理解app和UI。
- 更易複用,同樣的展示元件可以在不同的狀態源、資料來源中使用。也可以封裝成容器元件,在未來重用它們。
- 展示元件是app的調色盤。你可以把它們放到單獨的頁面,並讓設計師來調整它們的樣式和結構,而不用改變app的邏輯。單獨的頁面有靜態性,你可以在上面進行screenshot regression測試。
- 這種方法會強迫你去解析佈局相關的元件,比如Sidebar, Page, ContextMenu,強迫你去使用this.props.children,而非在不同容器中不斷複製jsx那塊地方。
記住,react的元件不一定要生成DOM,它們只需要考慮如何設計UI之間的分界與組合關係。利用好這一點。
什麼時候引入容器?
我的建議是,你最好先做展示元件。當你意識到,有一些中間元件傳遞了過多的props,有一些元件並不使用它們繼承的props而只是將這些props傳遞給他們的子級,而且每次子級元件需要更多資料時,你都需要重新調整或編寫這些中間元件,那麼,這時候你可以考慮引入容器元件了。這樣做,你可以傳遞props和方法給末端的子級元件,而不必麻煩一些不相關的中間元件。
這是一個邊寫邊改的重構,所以不必一步到位。你嘗試著這種模式,慢慢地會培養起一種對何時引入容器的直覺,就像你知道何時該增加函式一樣。我的redux教程也許會幫助你哦
其他二分法
容器元件和展示元件的分別並不被嚴格定義,理解這一點很重要。為了對比,我再列舉一些相關(但是不同的)的二分法。
多狀態變數和少狀態變數
有些元件用<code>setState()</code>,有些不用。容器元件通常多狀態變數,而展示元件卻不,這不是鐵規律。展示元件也可以多狀態變數,而容器元件也可以少狀態變數。
類與函式
自從React0.14,元件可以被宣告為類,也可以被宣告為函式。定義函式方便,卻少了類獨有的特性。有些限制或許會在未來消失,但是它們至少是存在的。因為函式容易理解,所以我推薦使用函式,除非你需要那些,現在只有類才有的狀態管理,lifecycle hooks,效能優化等特性。
純的不純的
人們說一個元件純,是指給予它一樣props和state,它保證能輸出一樣的結果。純函式可以是類,可以是函式,可以多狀態,可以無狀態。Another important aspect of pure components is that they don’t rely on deep mutations in props or state, so their rendering performance can be optimized by a shallow comparison in their shouldComponentUpdate() hook。目前只有類可以定義<code>shouldComponentUpdate()</code>,或許將來有改變吧。
展示元件和容器元件都有上述的二分特性。在我看來,展示元件傾向於少狀態、純的函式,容器元件傾向於多狀態,純的類。當然啦,這只是個人觀察,而非規則,我也見過完全相反的情況。
不要將展示元件和容器元件當作教條。有些時候,不必劃出清晰的線條,也不用覺得劃出區分會很困難。如果你分不清某個元件是展示元件還是容器元件,也許是為時尚早。要知道,心急吃不了熱豆腐。
例子
This gist by Michael Chan 討論了這個
延伸閱讀
Getting Started with Redux
Mixins are Dead, Long Live Composition
Container Components
Atomic Web Design
Building the Facebook News Feed with Relay
相關文章
- 【譯】展示型元件和容器型元件(作者:Dan Abramov,Redux的開發者)元件Redux
- 翻譯:展示元件和容器元件元件
- 致敬 React: 為 Vue 引入容器元件和展示元件ReactVue元件
- React函式式元件和類元件[Dan]React函式元件
- 詳解展示元件和容器元件的區別和應用元件
- React 快速上手 - 06 元件設計 容器元件、展示元件、操作元件React元件
- [譯]react的setState如何知道該做什麼 --Dan AbramovReact
- 【譯】容器元件 (Container Components)元件AI
- [譯] React 中的 dumb 元件和 smart 元件React元件
- [譯] 元件、Prop 和 State元件
- [譯]React函式元件和類元件的差異React函式元件
- vue實現登入和個人資訊元件展示Vue元件
- [譯文]如何實現一個單檔案元件元件
- Flutter學習筆記(10)--容器元件、圖片元件Flutter筆記元件
- Container容器元件的使用AI元件
- Vue元件、元件傳值和元件插槽Vue元件
- [譯] 無渲染元件元件
- Kerberos的元件和術語(翻譯和註解)ROS元件
- map元件如何展示marker的callout氣泡元件
- Flutter 容器控制元件篇-->ScaffoldFlutter控制元件
- 微信小程式-檢視容器元件微信小程式元件
- winform 自定義容器控制元件ORM控制元件
- [譯] 單元素元件模式簡介:使用 React 或其它元件庫建立可靠元件的規則和實踐元件模式React
- 【譯】懶載入元件元件
- [譯] React 路由和 React 元件的愛恨情仇React路由元件
- 「譯」React 專案結構和元件命名之道React元件
- HarmonyOS ArkTS元件 | Flex 以彈性方式佈局子元件的容器元件 學習記錄元件Flex
- React受控元件和非受控元件React元件
- 一文了解如何原始碼編譯Rainbond基礎元件原始碼編譯AI元件
- VUE實現評分效果和不同型別分數展示效果元件Vue型別元件
- Flutter 容器控制元件篇-->MaterialAppFlutter控制元件APP
- Flutter 容器控制元件篇-->ContainerFlutter控制元件AI
- Flutter滾動型容器元件 - ListView篇Flutter元件View
- 視覺化搭建 - 容器元件設計視覺化元件
- C# 容器上控制元件排序C#控制元件排序
- 【譯】 React官方:函式元件與類元件的差異 ?React函式元件
- 元件規範和生命週期——react文件翻譯元件React
- [譯] 深入 React 高階元件React元件