04-组件设计方法
在初步确定了 model 的设计方法以后,让我们来看看如何设计 dva 中的 React 组件。
组件设计
React 应用是由一个个独立的 Component 组成的,我们在拆分 Component 的过程中要尽量让每个 Component 专注做自己的事。
一般来说,我们的组件有两种设计:
- Container Component
- Presentational Component
Container Component
Container Component 一般指的是具有监听数据行为
的组件,一般来说它们的职责是绑定相关联的 model 数据
,以数据容器的角色包含其它子组件,通常在项目中表现出来的类型为:Layouts、Router Components 以及普通 Containers 组件。
通常的书写形式为:
import React, { Component, PropTypes } from 'react';
// dva 的 connect 方法可以将组件和数据关联在一起
import { connect } from 'dva';
// 组件本身
const MyComponent = (props)=>{};
MyComponent.propTypes = {};
// 监听属性,建立组件和数据的映射关系
function mapStateToProps(state) {
return {...state.data};
}
// 关联 model
export default connect(mapStateToProps)(MyComponent);
Presentational Component
Presentational Component 的名称已经说明了它的职责,展示形组件,一般也称作:Dumb Component,它不会关联订阅 model 上的数据,而所需数据的传递则是通过 props 传递到组件内部。
通常的书写形式:
import React, { Component, PropTypes } from 'react';
// 组件本身
// 所需要的数据通过 Container Component 通过 props 传递下来
const MyComponent = (props)=>{}
MyComponent.propTypes = {};
// 并不会监听数据
export default MyComponent;
对比
对组件分类,主要有两个好处:
- 让项目的数据处理更加集中;
- 让组件高内聚低耦合,更加聚焦;
试想如果每个组件都去订阅数据 model,那么一方面组件本身跟 model 耦合太多,另一方面代码过于零散,到处都在操作数据,会带来后期维护的烦恼。
除了写法上订阅数据的区别以外,在设计思路上两个组件也有很大不同。 Presentational Component
是独立的纯粹的,这方面很好的例子,大家可以参考 ant.design UI组件的React实现 ,每个组件跟业务数据并没有耦合关系,只是完成自己独立的任务,需要的数据通过 props
传递进来,需要操作的行为通过接口暴露出去。 而 Container Component
更像是状态管理器,它表现为一个容器,订阅子组件需要的数据,组织子组件的交互逻辑和展示。
更多的相关内容,可以看看Redux作者(facebook的程序员)Dan Abramov 的看法:
- https://github.com/reactjs/redux/issues/756
- https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
接下来我们会进入本例中组件的设计开发,从实践一步一步看看如何贯穿起来。
下一步,进入组件设计实践。