Headless UI 和 React Hooks
在 React 中,基于类组件存在如下缺点
- 内部状态难以复用
- 代码较为复杂以及散乱的生命周期函数
而 React Hooks 赋予了在函数组件中,管理状态,管理副作用(可以近似模拟生命周期)的同时,也推动了组件的拆分及复用。在 React Hooks 基础上,Headless UI 应运而生。
Headless UI
业务逻辑
Headless UI 顾名思义,就是没有 UI 的组件,即组件只提供业务逻辑,UI 则由开发者自己提供。
什么是业务逻辑?业务逻辑,指的此次开发功能的目的和达成目的的步骤,例如我想开发一个简易计算器,那么计算器的业务逻辑就是
- 得到一个数字(用户输入)
- 得到一个运算符(用户输入)
- 得到一个数字(用户输入)
- 输出结果
我只要能够实现上述业务逻辑,那么无论这些按钮是长还是圆,颜色是绿还是红,在 Input 输入还是在 Textarea 输入,都是属于 UI 范畴了,在业务逻辑层面是无需关心的
那么,我提供如下的接口即可满足计算器的业务逻辑
UI
const { inputPrefix, inputSymbol, inputAfter, getResult } = useCalculator();什么是 UI?UI(User Interface) 指的是用户界面,即用户看到的界面,例如上述的计算器,我需要提供如下的 UI 组件
- 一个输入框
- 一些运算符按钮(+,-,*,/)
- 一个输入框
- 一个计算结果按钮
- 一个显示结果的地方
我提供通用的业务逻辑接口,而具体的 UI 组件,则由开发者自己提供,例如如下的 UI 组件
// 这是业务逻辑const { inputPrefix, inputSymbol, inputAfter, getResult } = useCalculator();
// 这是UIconst<p>{result}<p><Input onChange={inputPrefix}><SymbolsGroups onClick={inputSymbol}><Input onChange={inputAfter}><Button onClick={() => result = getResult()}>据此我已实现了计算器的所有功能了,在实现功能的同时还具有如下特点
- 复用性,高度抽象的业务逻辑,原则上来说可以在任何地方复用(在跨语言或框架有所区别,但是思路相同)
- 扩展性,举个例子,我现在想增加一个【清空】按钮,那么我只需要在业务逻辑中增加一个清空按钮的逻辑,然后在 UI 中增加一个清空按钮的 UI 组件即可,无需修改以前的逻辑
- 可测试性,因为业务逻辑是高度抽象的,所以可以很方便的进行测试,而 UI 组件则需要开发者自己提供测试代码,当然 UI 测试不太容易编写
- 效率和成本 a. 需要剥离业务和 UI,而我理解前端本身就是偏向 UI 的,所以需要更高的抽象思想,开发者要求会更高 b. 需要开发者自己提供 UI 组件,成本还挺高,没有用组件库快
今年最火的 chakra-ui 组件库就是这么设计的
- 底层,提供 Headless UI,可完全自己定制 UI
- 上层,提供完整的 UI 组件,可以直接使用
Headless 的思考
业务的本身是为了产生收益,而产生收益的是产品售卖,信息售卖,服务等等,从极端点角度来说,UI 并不能创建收益,UI 仅仅是为了引导用户来创建收益,用户无需通过 UI,通过指令也是一样可以创建收益
所以说 UI 是业务后续的表现形式,将业务逻辑和 UI 拆分开是最为合适的。业务逻辑较为纯粹,是可以测试的,无论后续怎么改,只要测试能跑通就不会出大问题
关于业务逻辑和复用这件事,其实可以参考后端,在后端只有一套数据模型,同时可以一套接口来接入 PC 端,小程序端等等,没有说针对 PC 端搞一套数据模型和业务逻辑,针对小程序又是另一套