组件
组件是 UI + 逻辑的复用,但逻辑复用能力等于 0。
一个 React 项目,是由无数个大大小小的组件组合而成的。在 React 的世界中,组件是一等公民。而咱们平时拆分组件的依据无非是:尽可能的复用代码。
组件是 UI + 逻辑的复用,你不能将 UI 和逻辑拆开。好比 Antd 的
Cascader 级联选择 组件,内置了样式和级联选择的逻辑,用户使用的时候至关于一个黑盒,只管用就好了。可是有一个很现实的问题,当该组件的样式不能知足咱们需求的时候,咱们须要从 0 从新实现一个组件,重写 UI + 逻辑,哪怕逻辑真的如出一辙。组件的逻辑复用能力等于 0。我能够想到一个可怕的事实,社区上的同类组件,大部分的逻辑都是能够复用的,只是在样式上有差别,但逻辑共享在社区上并无很流行。
HOC 与 Render Props
HOC 与 Render Props 能够把逻辑抽出来复用,但并无让逻辑复用流行起来。
固然,我上面说的不能复用有点夸张,React 提供了 HOC 与 Render Props 两种方式来解决逻辑复用的问题。好比下面的监听鼠标位置的逻辑,咱们就能够经过 Render Props 来复用。
<Mouse>
(position)=> <OurComponent />
</Mouse>复制代码
同类逻辑包括监听 window size,监听 scroll 位置等等。可是咱们通常不多用 render props 来封装逻辑,更少去和其它项目去共享逻辑。为何呢?想一想多个逻辑复用会怎么样,你就知道多可怕了。
<WindowSize>
(size)=> (
<Mouse> (position)=> <OurComponent size={size} mouse={position}/> </Mouse> ) </WindowSize>
复制代码
嵌套地狱的代码是咱们不能忍受的,同时 HOC 也存在相似的问题,这多是致使逻辑复用不能流行起来的一个重要缘由。
React Hooks
React Hooks 很好的解决了逻辑复用的问题,同时社区中诞生了一批比较好的 React Hooks 库。
React Hooks 是今年 React 的一个重磅炸弹,在社区引发了激烈的回响。随着 Hooks 的诞生,咱们能够经过 Custom Hooks 很方便的封装逻辑,逻辑共享也成为了潮流。好比上面的例子,咱们就能够经过
react-use 很方便的实现。
import {useMouse, useWindowSize, useScroll} from 'react-use'
function Demo(){
const mousePosition = useMouse();
const windowSize = useWindowSize();
}
复制代码
react-use 是社区中比较优秀的 Hooks 库,封装了不少经常使用的基础逻辑,在平常开发中必不可少。可是只用 react-use 就够了吗?显然不是。react-use 中的 Hooks 粒度比较小,相似于工具库。
而在中台产品中,有不少特定的场景逻辑,须要多个 Hooks 进行组合,或者定制特定的逻辑。在蚂蚁内部,有很是多的中台应用,开发者在各自项目中沉淀了各类好用的 custom Hooks,咱们把这些好用的逻辑拿出来,建立了
@umijs/hooks ,定位为为中台场景服务的 Hooks 库。
@umijs/hooks
@umijs/hooks 是面向中台应用场景的 Hooks 库,封装了中台常见场景的逻辑,让中台开发变得超级简单。@umijs/hooks 已经在蚂蚁金服多个产品中落地,口碑很好,提效明显。固然,你可能不信,口说无凭,那就用例子来讲话。
useAntdTable
中台开发中,table 页面应该算最多的一个了,咱们通常会使用 Antd 的
Table 组件来搭建,可是其中仍是有不少逻辑,咱们是没法避免的。
-
page,pageSize管理
-
page,pageSize 变化时从新进行异步请求
-
筛选条件变化时,重置 page,并从新请求数据
-
异步请求的 loading 处理
-
异步请求的竞态处理
-
组件卸载时丢弃进行中的异步请求(不少人一般不处理,在某些状况会报警告)
上面的逻辑,咱们在几乎全部的 table 页是必需要处理的,想一想均可怕。useAntdTable 至少封装了上面 6 个逻辑,
一行代码封装全部逻辑,列表页开发从未变得如此简单。
const { tableProps } = useAntdTable(asyncFn);
const columns = [];
return (
<Table columns={columns} rowKey="id" {...tableProps} />
)
复制代码
useSearch
-
防抖
-
异步请求的 loading 处理
-
异步请求的请求时序控制
-
组件卸载时取消防抖及异步请求等逻辑
const { data, loading, onChange } = useSearch(asyncFn);
<Select
onSearch={onChange}
loading={loading}
>
{data.map((item)=><Option />)}
</Select>
复制代码
更多的 Custom Hooks
固然,咱们还有更多极大提效的 Custom Hooks,你能想象
不用写一行逻辑,就能实现异步 loadmore 功能吗?(
useLoadMore)
基础 Hooks
react-use 应该是目前发展最好的 Hooks 库,可是咱们正在逐渐放弃它,最大的缘由是版本升级太快,你能想象几个月以前我项目中用的是 v9,如今已是 v13 了吗?我已经不知道怎么去升级了。
为了解决这个问题,@umijs/hooks 也沉淀了平常工做中频繁使用的基础 Hooks,包括经常使用的 useAsync,useDebounce,useBoolean,useMouse 等等,而且还在不断发展。也许只用 umi hooks 就够了。
写在最后
umi hooks 让中台开发变得如此简单,我能想象,不久的未来,中台开发能够不用写一行逻辑,这也是咱们为之奋斗的目标。
同时,但愿更多的人参与进来,你能够提供好的 idea,也能够将平常封装的 Hooks 贡献上来,让 umi hooks 更加丰满,让更多的人收益。