作者:王柯
Choerodon猪齿鱼平台使用 React 作为前端应用框架,对前端的展示做了一定的封装和处理,并配套提供了前端组件库Choerodon UI。结合实际业务情况,不断对组件优化设计,提高代码质量。
本文将结合Choerodon猪齿鱼平台使用案例,简单说明组件的分类、设计原则和设计模式,帮助开发者在不同场景下选择正确的设计和方案编写组件(示例代码基于ES6/ES7的语法,适于有一定前端基础的读者)。
文章的主要内容包括:
- React 组件简介
- 组件分类
- 组件设计原则、最佳实践
- 组件设计模式简介
React 组件简介
React是指用于构建用户界面的 JavaScript 库。换言之,React是一个构建视图层的类库(或框架)。不管 React 本身如何复杂,不管其生态如何庞大,构建视图始终是它的核心。
可以用个公式说明:
UI = f(data)
React的基础原则有三条,分别是:
- React 界面完全由数据驱动;
- React 中一切都是组件;
- props 是 React 组件之间通讯的基本方式。
那么组件又是什么?
组件是一个函数或者一个 Class(当然 Class 也是 function),它根据输入参数,最终返回一个 React Element。简单地说,React Element 描述了“你想”在屏幕上看到的事物。抽象地说,React Element 元素是一个描述了 Dom Node 的对象。
所以实际上使用 React Component 来生成 React Element,对于开发体验有巨大的提升,比如不需要手写React.createElement等。
那么所有 React Component 都需要返回 React Element 吗?显然是不需要的。 return null; 或者返回其他的 React 组件都有存在的意义,它能完成并实现很多巧妙的设计、思想和副作用,在下文会有所扩展。
可以说,在 React 中一切皆为组件:
- 用户界面就是组件;
- 组件可以嵌套包装组成复杂功能;
- 组件可以用来实现副作用。
React 也提供了多种编写组件的方法适用于各种场景实例。
组件分类
如何在场景下快速正确地选择组件设计模式和方案,首先得有一个自己接受和常用的组件分类,以便从分类中快速确定编写方法,再考虑设计模式等后续问题。
Vue的作者尤雨溪在一场Live中也表达过自己对前端组件的看法,“组件可以是函数,是有分类的。”从功能维度对组件进行了分类,这四种分类方式也适用于Choerodon猪齿鱼前端开发中的业务场景:
- 纯展示型组件:数据进,DOM出,直观明了
- 接入型组件:在React场景下的container
- component,这种组件会跟数据层的service打交道,会包含一些跟服务器或者说数据源打交道的逻辑,container会把数据向下传递给展示型组件、
- 交互型组件:典型的例子是对于表单组件的封装和加强,大部分的组件库都是以交互型组件为主,比如说Element UI,特点是有比较复杂的交互逻辑,但是是比较通用的逻辑,强调组件的复用
- 功能型组件:以Vue的应用场景举例,路由的router-view组件、transition组件,本身并不渲染任何内容,是一个逻辑型的东西,作为一种扩展或者是抽象机制存在
在此以Choerodon猪齿鱼平台的一个创建界面来分析。
- 红色布局:功能型组件
- 蓝色菜单:交互型组件,菜单项:遍历菜单数据输出DOM的纯展示型组件
- 右块内容:接入型组件(容器组件)
- Table、btn等:交互型组件
可以看到,一个复杂界面可以分割成很多简单或复杂的组件,复杂组件还包括子组件等。此外,除了从功能维度对组件进行划分,也可以从开发者对组件的使用习惯进行分类(以下分类非对立关系):
- 无状态组件
- 有状态组件
- 容器组件
- 高阶组件
- Render Callback组件
简单说明一下几种组件:
- 无状态组件:无状态组件(Stateless Component)是最基础的组件形式,由于没有状态的影响所以就是纯静态展示的作用。基本组成结构就是属性(props)加上一个渲染函数(render)。由于不涉及到状态的更新,所以这种组件的复用性也最强。例如在各UI库中开发的按钮、输入框、图标等等。
- 有状态组件:组件内部包含状态(state)且状态随着事件或者外部的消息而发生改变的时候,这就构成了有状态组件(Stateful Component)。有状态组件通常会带有生命周期(lifecycle),用以在不同的时刻触发状态的更新。在写业务逻辑时常用到,不同场景所用的状态和生命周期也