React Native 第六天
Presentational and Container Components(译文)
译自(https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)
当作者在编写React程序时,发现了一个简单却十分有用的模式。如果你已经使用react一段时间了,有可能你已经发现它了
这篇文章
很好的解释了它,这篇文章会补充一些观点。
如果你将组件分割到两个类别中你会发现你的组件很容易复用,作者把他们称作容器组件和展示组件,作者也听到过其他一些称呼
胖子和瘦子,聪明和愚蠢,稳固和纯净,屏幕和组件…,这些名称虽然不是一模一样,但是核心想法是相似的。
作者的展示组件
- 关心事物展现的外观
- 可能会包含展示组件和容器组件一起,通常它们各自拥有相同的DOM标签和样式
- 通常允许通过this.props.children 进行控制
- 对app其他部分没有依赖,比如flux action 或stores
- 不指定数据如何加载或改变
- 只通过props接收数据和回掉
- 很少拥有自己的状态(当拥有时,应该是UI的状态而不是数据)
- 除非组件需要状态,生命周期钩子,或者性能优化时可以用functional component编写
- 举例 :Page, Sidebar, Story, UserInfo, List.
作者的容器组件
- 关心事物如何运行
- 可能同时包含展示组建和容器组件,但是通常没有任何DOM标签(除了一些最外层DIV标签),也不会有任何样式代码
- 提供数据和行为给展示组件或者其他的容器组件
- 调用FLUX action 并且提供这些作为回调给展示组件
- 通常是有状态的,因为他们通常作为数据源
- 一般使用高级组件生生,就像React Redux的connect(),elay的createContainer(),Flux Utils的Container.create(),而不是手写
-
举例: UserPage, FollowersSidebar, StoryContainer, FollowedUserList
通常,我将两种组件放在不同的文件夹下,以便区分
这样做的好处
- 更好的关注点分离。用这样的方式写自己的组件能更好理解app和ui
- 更好的复用性。你可以使用同一个展示组件却是不同的状态源,把这种方式变成两个不同的容器组件,这样可以进一步增强复用性
- 展示组件实际上是你app的调色板,你可以将它们放在单个页面上,UI设计师可以随意更改界面,而不必触及app的逻辑部分
-
这会强制你提取布局组件,如側邊欄,頁面,上下文菜單,用this.props.children 代替,而不是在几个容器组件中复制相同的标记和布局
NOTE:组件不必发出DOM,他们只需在UI关系之间提供组合边界 |
利用这一点
什么时候引进容器组件
作者建议,刚开始构建你的app时只需要展示组件,最后你会发现,你需要传递太多的props在中间组件上
当你注意到一些组件不用它们接收到的props,但是向下传递接收到的props,这时你需要重写这些中间组件
,任何时候子组件需要更多的数据就是一个好的时机来引入一些container组件,这种方式你可以放一些数据
和行为props到子组件上而不必负担书中间无关的组件。
这是一个持续进行的重构过程,所以不要期望在最开始的时候就把它做正确,当你实验这个模式的时候,
你将会对什么时候提取一些container组件建立一种直观的感觉,就像你知道该什么时候提取方法一样。
Other Dichotomies
理解container和represent 两种组件的区别非常重要,两种组件不是技术上的不同,而是目的上的不同。
相比之下,有一些相关的(但不同的)技术区别:
- 有无state
一些组件使用setState,一些组件不使用。当容器组件往往是有状态的,展示组件往往是没有状态的,但这不是一个硬性规则。
- 函数式和类式
组建可以通过这两种方式创建,作者建议你使用函数式组件,除非你需要state,生命周期钩子,或者性能优化(此时你需要使用类组件)
- 纯净的和非纯净的
按例,如果一个组件保证传入相同的props和state 就会返回相同的结果,那么它就是一个纯净的组件。
纯净组件以类或函数方式创建,有无state都可以,纯净组件的另一个重要方面是他们不依靠深层的props和state
所以他们渲染的性能可以通过shouldComponentUPdate()的钩子里的浅比较进行优化。