小卢碎碎念之 React Hooks

此文主要是我的在使用了 react hooks 一段时间后, 对于 react hooks 的理解,也是一个碎碎念。各位大佬若是以为有什么问题能够提出来讨论讨论,也接受批评哦~vue

是什么

本质上看,好像每个Hooks都是一个函数吼。react

但,既然是函数,又为何要另起一个名字(概念)?小程序

因此, 写/用法上确定会与普通函数有些区别。api

与普通函数的异同

若是说, 咱们如今须要实现一个 TodoList 的增删需求。咱们能够函数, 和hooks 分别实现, 而后对比差别。安全

实现简单TodoList

利用闭包

利用闭包,咱们能够大概实现以下的逻辑块:闭包

使用Hooks

看上面 闭包hooks 分别实现的功能, 貌似也没啥区别吼。框架

那就继续往下, 看实际应用到 函数式组件 中的样子。dom

闭包逻辑在函数式组件中的使用

Hooks 在函数式组件中的使用

从上两个图能够发现。returnjsx 部分彻底相同, 能够舍去不看。注意力主要放在除了 return 以外的地方(也就是 return 以上的函数体部分)函数

首先咱们看 为了使用闭包逻辑,而对 组件进行调整的部分。单元测试

由于上图是结果, 一会儿看可能有些同窗有点蒙, 我将流程拆解下。

第一步、

由于要在组件初始化的时候去建立TodoList逻辑, 而且将其对外暴露的api进行保存, 因此, 咱们能够有以下代码。(一个建立, 一个保存)。

第二步、

接着,咱们就要把数据交给视图去渲染, 把逻辑交给视图来触发了, 该怎么写呢, 是这样吗?

若是这样写,有些同窗可能会发现, 怎么点击add 按钮咋子没得效果嘞。看逻辑没得错啊,用闭包函数提供出来的数据,也用它提供出来的api, 对数据进行增长, 可是为啥没得效果嘞!?

介里, 咱就得提一下关于 函数式组件的更新条件。

  1. 组件内部使用useState返回的setState 函数引发的state 变动,则会去引发当前组件的 rerender ;
  2. 组件外部传入的 props 变动,也会引发组件的 rerender;
  3. 第三个就是 useContext 了,当前组件使用的上下文中, 只要有一条数据变动, 就会引发该组件的 rerender (context 仍是得拆分的细一点 =.=)

更新条件介绍完毕, 回到主题, 好像咱们更改闭包函数内部数据, 一个条件都没和上面三个吻合的, 因此, 咱们得想个办法,每次更新了数据后,让函数式组件去 rerender

而这里就选用的第一种, 更新state来引发组件的rerender

说干就干, 首先,在组件内部增长一个 useState 来记录 list , 而后在每次对闭包函数内部的 list 进行增、删后, 都去获取最新值,并更新到视图上。

写完是这个样子啦, 而后去运行一下。。 。 没得问题, 美滋滋, 打卡下班,多么充实的一天~~~

直至N天后, 某个同事小吴要用到这个功能, 听着你给他讲, 要这么这么用, 要记录什么什么 state, 小吴怕是都要按不住手中的刀了。因此, 为了咱们的生命安全, 咱们要尽可能的站在小吴的角度,去考虑如何将一个功能更加内聚, 对外部的使用要求更小

此时, 也该 react hooks 闪亮登场了(废话了这么多, 干)

去除 return 部分, 咱们发现咱们要用 TodoList 的逻辑, 只须要增长如下一行

有点蒙?我再把 useTodoList 的代码拿过来

还有在组件中的使用

怎么样, 是否是很简洁。哈哈哈哈。

接下来咱们大概走一下这个hooks 的逻辑。

useTodoList 内部, 有记录一个 list 。以及有两个函数, 分别对list进行增长和删除。最后将 list,增长和删除逻辑return出去。而后外部组件中又去调用这增长删除逻辑, 修改了 hooks 中的数据, 然又引发外部组件的rerender

而此时, 则又涉及到了一个更新条件, 上面讲的三条函数式组件的更新条件, 此时也就得多加一条了

​ 4. 函数式组件中所用到的 hooks 中, 若是更新了 state, 则会依次由上往下(hooks 书写顺序),由内往外的触发 hooks函数式组件rerender

由此条件, 咱们才能在 hooks 中的数据变动的时候引发外部的视图更新。

其实, hooks 我的感受跟 函数式组件同样, 只不过hooks 抛出的是API,是一些逻辑处理函数。 而函数式组件抛出的是 Fiber Node, 是将要渲染到视图上的东西。

另外的, 提及hooks 和 闭包函数差别,hooks 内部能够用其余hooks, 以及经过 useEffect 来实现的一些 生命周期之类, 闭包函数则不行, 闭包函数要强行作, 还得外部去调用,那样对外部的要求又高了, 小吴的刀怕是两我的都按不住了。

因此,对于这个主题, hooks 与普通函数的异同, 总的来讲

  • hooks呢, 可使用 其余的 hooks , 用法跟函数式组件 一致, 只不过return的不是JSX, 而是一些 API 或者数据。固然这里讲的只是输出, 还有输入的, 如 useTodoList(['666']) 这种的

  • 对于函数, 咱们能够利用闭包现象,来写一段内聚的逻辑,而后暴露一些API给外部来操控内部的数据和逻辑。

可是 hooks 要求相对于闭包函数较高, 得运行在 react 环境中, 或者 vue3?(vue3 的 Composition API 对应 react 的话,应该就是 react hooks)vue3的还不太清楚 hooks 写法是否和 react 的一致,若是一致的话, 是否是一个 hooks 就能够在两个框架中共用?

插一句

接下来基本都是个人猜测, 没得实践过,你们能够来讨论讨论。

能够作什么

上面一点有讲到

hooks 我的感受跟 函数式组件同样, 只不过hooks 抛出的是API,是一段逻辑。 而函数式组件抛出的是 Fiber Node, 是将要渲染到视图上的东西。

因此, 针对一些比较复杂且公共的逻辑, 咱们就能够将逻辑封装成一个自定义hooks。供不一样UI来共享该逻辑。

若是激进一点, 咱们能够将 视图 和 逻辑彻底的分离, 一个组件分红两个, 一个逻辑的 hooks , 一个视图的 template, 可是感受这样写好像变成了Vue, 干, 具体仍是得去实践,看有啥优缺点。

单元测试

单元测试分 功能测试 和 UI测试。

功能测试对应 Hooks 的测试, 测试该 hooks 的逻辑是否正常。

UI测试对应 template 的测试, 测试输入固定数据, 视图有没有正确的渲染出来。

由 数据驱动视图( UI = render(State) ) 这一理念,咱们对于一个功能的测试, 彻底能够将重心放在 hooks 上, 对于 dom 的测试, 只须要测试数据有无正确渲染就行。而不须要 各类获取 dom,触发这个那个事件,事件里又去触发对应逻辑。

抽象来看, 咱们测试一块地方的功能, 分两层, 一层视图, 一层逻辑。 咱们与视图的交互,目的就是为了去触发某个逻辑。 视图只是用户与逻辑之间的一个媒介而已。因此测试的话, 我以为能够绕过繁琐的视图层操做。直接测试 hooks 功能。而视图则是侧重在固定的数据, 是否有固定的视觉呈现。(这个的前置条件就得是 视图与逻辑的分离)

纯JS/TS业务逻辑共用

若是说, 咱们有一个产品, 分为 PC端、H5端、RN端、Taro小程序端。 那是否能让这些不一样端都共享同一套业务逻辑代码?

写在最后

线上代码连接点击这里

以上基本全是本人在使用了 hooks 一段时间后的, 对于hooks 的理解, 以及对一些实践方式的猜测。

也欢迎各位大佬一块儿来参与讨论。

相关文章
相关标签/搜索