Hooks 二三事 (2) | 可视化对比引入 Hooks 前后代码量

上一篇文章中,提及 「Hooks 就是让你更容易做你已经在做的事情」。那么”容易“二字体现在哪里呢?今天要分享的这篇文章就从可视化角度,量化用 Hooks 重构组件前后的代码量,并探讨在思维模式上的转变。
原文链接:https://wattenberger.com/blog/react-hooks

一年前,React 团队提出了 Hooks,改变了社区内很多开发者的开发习惯。网上有大量的文章在介绍 Hooks 的基本功能 ,但本文将探讨 ”类组件“ 与 ”函数组件 + Hooks“ 两种开发模式下思维方式的转变。

生命周期

  • 在类组件中,我们会在特定的生命周期函数中进行更新操作。

  • 在函数组件中,我们使用 useEffect 钩子在必要的生命周期中执行代码。

图1

通过这个示例,你可能会想:”好吧,useEffect 就是提供了一种在生命周期中执行代码的新方式。“ 然而,这个结论是不够全面的。接下来一起看看这个更为完善的例子,比如有一个计算开销很大的 getDataWithRange() 函数,该函数根据指定的 dataRange 返回筛选后的数据。这该怎么办呢?为了减少重复的计算开销,我们会希望把它存储到 state 对象中,当且仅当 dataRange 发生改变时才更新它。

  • 使用生命周期中的事件,我们需要在某一个点上处理所有的变化。我们的思考过程是这样的:“当组件开始加载和参数发生变化时(特指 dataRange ),更新 data 状态”。
  • 在函数组件中,我们需要思考的是哪些数据需要保持同步,思考的过程会是:“ data 需要与 dataRange 保持同步” 。
图2

这样的思考过程是不是简化了许多。但是,上述的例子中,我们依旧是在类组件的思想框架中思考问题。我们将 data 存储到 state 中,以此来避免每次组件更新中重新计算 data 值。现在,我们完全可以不用 state!Hooks 提供了 useMemo 方法来解决这个问题,当且仅当依赖数组内的任一元素发生变化时,才重新计算 data 值。

图3

更新上下文

是否还觉得不够直观?那就再看看这个更加复杂的例子吧,可以让你更深刻的体会到两种思考模式的认知负担差距。

假设我们在组件中有很多需要实时计算的值,它们依赖于不同的 props。比如,我们需要计算:

  • data:当 dataRange 改变时更新;
  • dimesions:当 margins 改变时重新计算;
  • scales:当 data 改变时需要同步更新。

在函数组件中,我们能够快速快速逻辑关系,比如“让 dimesionsmargins 保持同步”。

即使在这样简单的示例中类组件也显得特别笨重。这是因为我们有很多声明类的代码,用来解释如何使代码中的变量与 propsstate 保持同步,而在函数组件中, 我们只需要关注哪些数据需要保持同步。

注意,我们在代码中使用了很多次 useMemo() 钩子,以此拉近依赖项副作用的“距离”

宽松地定义状态

再加点逻辑,如果 scales 需要根据图表中的 dimension 改变,又该怎么做呢?

  • 在类组件中,我们需要对比 prevState 和当前的 state
  • 在函数组件中,hooks 并不关心依赖数组中的 marginsdimesion 是来自于 state 还是 props,还是两者都不是,对它而言,值就是一个值。
image-20200721142731529.png

总结

代码简洁

代码量少不一定容易阅读,让保持组件代码的简洁一定是一种胜利。接下来让我们快速比较一下上述示例的代码行数吧:

图4

<center>从左到右为上述的 5 个示例代码量,左边的柱状长度表示「类组件」代码行数,右边的柱状长度表示同样功能下的「函数组件+ Hooks」代码行数</center>

函数组件的平均代码行数是类组件的 46.1%。另外,再比较一下核心版本中主要的代码差异:

图5

堆叠图中每层的颜色与示例动图中的连接带颜色保持一致

可以看到我们是如何按功能逻辑将相关代码统一到一起的,而不是分散在多个生命周期事件中。

逻辑复用

Hooks 赋予了我们在组件之间共享功能逻辑的能力,而不需要去操作组件的生命周期事件。当然,使用类组件的编写模式时,你也可以利用高阶组件来实现这一需求,但是高阶组件所带来的麻烦比它创造的价值更多,经常把 render 函数搞得一团糟。

我(Amelia Wattenberger )从参与的众多项目中提取并维护了一个简单的 Hooks 仓库,降低了开发成本。从我的角度来讲,复杂功能逻辑的复用带来的便利包括:

  • 不必重复一些通用模式,比如:保证图表的比例与容器一致。在实现上,会是逻辑复杂、行数不少的代码块,如果需要不断在每个图表中实现,将是令人奔溃的。
  • KISS (Keep it simple and stupid)——让我在思考的时候能够专注于某一个点,确保我不会漏掉某个重要的环节,比如解绑事件等。

译者言

个人的一些看法:

  • 文中使用的案例代码都相对简单,但量化的过程是个不错的方法,我们有没有办法在实际项目中通过打点的方式做类似的比较呢;
  • 文中提到的 useMemo 的使用,也许可以作为可视化保持复杂数据同步的一个规范;
  • Hooks 在功能逻辑复用上面的优势,可以通过建立团队内部的 hooks 仓库发挥出来。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容