本文译自
Presentational and Container Components,文章的作者是
Dan Abramov,他同时也是Redux和Create React App的作者。在实际运用React + Redux 手艺栈的开辟过程当中,非常好的明白了容器型组件和展现型组件的看法是开辟出易保护,可复用React App的基本
在开辟React运用的时刻,我发明了一种极为简朴的开辟形式。假如你已用过一段时间的React,你或许已发明了它。这篇文章已讲的很好了,然则我想补充几点。
假如你将组件分为两类,你会发明它们更轻易被复用和明白。我把这两类称为容器型组件 和 展现型组件 ,然则我也听说过其他名字,比方痴肥型组件和简朴型组件,智能型组件和傻瓜型组件,有状况组件和纯组件,封装型组件和元组件等等。它们不完整雷同,然则在中心看法上是类似的。
展现型组件
- 体贴数据的展现体式格局
- 内部能够包括展现型组件和容器型组件,而且一般存在其他DOM元素及其款式
- 许可经由过程
this.props.children
掌握组件 - 不依赖app中的别的文件,像Flux的actions或stores
- 不体贴数据是怎样加载和变化的
- 仅经由过程
props
吸收数据和回调函数 - 险些不必组件内的
state
(假如用到的话,也仅仅是保护UI状况而不是数据状况) - 除非须要用到
state
,性命周期函数或机能优化,一般写成函数式组件, - 比方:
Page
,Sidebar
,Story
,UserInfo
,List
容器型组件
- 体贴数据的运作体式格局
- 内部能够包括展现型组件和容器型组件,然则一般没有任何用于本身的DOM元素,除了一些用于包裹元素的
div
标签,而且不存在款式 - 为展现型组件和容器型组件供应数据和操纵数据的要领
- 挪用Flux actions并以回调函数的体式格局给展现型组件供应actions
- 一般是有状况的,而且作为数据源存在
- 一般由高阶函数天生比方React Redux的
connect()
,Realy的createContainer
,或许Flux Utils的Container.create()
,而不是手写的 - 比方:
UserPage
,FollowersSidebar
,StoryContainer
,FollowedUserList
为了清楚的辨别这两种组件,我把放在差别的文件夹中
这类要领的上风
- 关注点星散。经由过程用这类体式格局开辟组件,你能够更好的明白你的app和UI
- 更好的复用性。你能够在差别的数据源中运用雷同的展现型组件,也能够把它们放进差别容器型组件中更进一步的举行复用
- 展现型组件是你的app必不可少的”调色板”,你能够把它们放在一个自力的页面中,让设计师随便拖拽它们的变量而不转变运用的逻辑。在这个页面上举行页面快照回归测试
- 这类要领逼你去把用于规划的组件抽出来,比方
Sidebar
,Page
,ContextMenu
。然后经由过程子组件的体式格局引入而不是在各个容器型组件中复制粘贴已有的款式和规划
记着,组件不一定要输出DOM元素,它们只须要供应UI之间的组合关联和分界
好好应用这一点
什么时刻引入容器?
我发起你先用展现型组件搭建你的app。终究你会心识到你给中心的组件通报了太多的props。有些组件并不运用这些props,而仅仅向下通报。而且当基层组件须要更多数据的时刻,你必需重写改写一切的中心组件。这时刻就须要引入一些容器型组件。经由过程这类体式格局,你能够从恭弘=叶 恭弘子节点组件猎取数据和要领,而不必斟酌处于中心的组件。
这须要边开辟边重构,所以没有必要一次做对。跟着一样平常运用这类形式,你会组件培养出一种『这时刻我该抽出一个Container』的直接,就像你已晓得什么时刻应当提掏出一个函数一样。我的Redux教程能够也会帮你一把
其他的二分法
展现型组件和容器型组件这类分类并不是非常严厉,这是根据它们的目标举行分类。
为了与之前的看法做比较,这是一些相干但差别的二分法
- 有状况和无状况 有些组件运用React的
setState()
要领,有些不必。容器型组件往往是有状况的而展现型组件往往是无状况的,这并不是一条铁律。展现型组件也能够是有状况的,容器型组件也能够是无状况的 - 类和函数 从React0.14最先,组件既能够声明为类也能够声明为函数。函数式组件能够定义的更简朴然则也缺乏一些只能在类组件中运用的特写。有些限定能够将来会消弭,然则在当下仍然是存在的。因为函数式组件越发易于明白,所以我发起你只管的运用它。除非你须要
state
,性命周期函数,或许机能优化,这些特征只要在类组件中才能够运用。 - 纯和非纯 假如一个组件在输入雷同
props
的状况下老是输出雷同的效果,那我们称这个组件为pure component。pure component既能够声明为类组件也能够声明为函数式组件,即能够是有状况的也能够是无状况的。另一个主要的方面是,pure component不依赖props
和state
的深层比对,所以能够在shouldComponentUpdate
要领中举行浅比较优化机能,然则在将来能够有许多变化。
展现型组件和容器型组件都能够放进以上任何一种二分法中。在我看来,展现型组件往往是无状况的纯函数组件,容器型组件往往是有状况的纯类组件。然而这并不是一种请求,而是一种征象,而且在一些特定的场景中我也确切见过完整相反的状况。
不要把展现型组件和容器型组件的分别当做教条。有的时刻没有必要对两者举行辨别。假如你不太肯定一个组件是展现型组件照样容器型组件,或许如今还不是辨别它的时刻,别太心急!
例子
Michael Chan为我们用一个gist阐释了上面的原理