跟着官方文档能学懂React Hooks就怪了

大家好,我是若川。今天分享一篇关于「React Hooks」的好文。欢迎点击下方卡片关注我。

以下是正文~


回想下你入门Hooks的过程,是不是经历过:

  1. 类比ClassComponent的生命周期,学习Hooks的执行时机

  2. 慢慢熟练以后,发现Hooks的执行时机和生命周期又有些不同。比如componentWillReceiveProps对应哪个Hooks

  3. 感到困惑,去搜一些Hooks原理层面的文章阅读

作为一个API,不该简简单单、可可爱爱的照着文档调用就行么,Hooks为什么这么难?

React官方也发现了这个问题,在React要重写文档了讲到,React要基于Hooks重写文档。

本文主要包括2方面内容:

  1. 解释Hooks难学的原因

  2. 给出学习Hooks的建议

React的底层架构

可以用一个公式概括React

const UI = fn(state);

视图可以看作状态经过函数的映射。

用户与界面的交互,可以看作这个公式的不断执行。

这个公式太精简了,没有解释state(状态)从哪儿来,我们扩展下:

const state = reconcile(update);
const UI = fn(state);
  1. 用户交互产生update(更新)

  2. update经过reconcile步骤计算出当前应用的state

  3. fnstate映射为视图变化(UI)

我们给fn起个名字:commit

const state = reconcile(update);
const UI = commit(state);

那么update在哪里产生呢?当然来自于用户交互,比如:点击事件。

所以React的底层架构可以简化为三步:

  • 用户交互产生update

  • state = reconcile(update);

  • UI = commit(state);

了解了底层架构,我们再来看通过类比ClassComponent学习Hooks会带来的问题。

生命周期函数的抽象层级

我们已经有了完整的驱动视图更新的底层架构,开发者该怎么操作这套架构呢?

可以用计算机的抽象层级来类比:

高层:应用程序
中层:操作系统
底层:计算机组成架构

对应React

高层:应用程序       ClassComponent生命周期
中层:操作系统       介入架构的API
底层:计算机组成架构  React底层架构

可以看到,生命周期函数属于抽象程度比较高的层次。这么设计也是为了让开发者更容易上手React

设想一个Vue2开发者要转React技术栈,只需要类比Vue的生命周期来学习React的生命周期就行了。

这一切在Hooks到来前都没问题,然而......

Hooks的抽象层级

Hooks属于中等抽象层级。也就是说,Hooks直接介入底层架构的运行流程。

高层:应用程序       
中层:操作系统       Hooks
底层:计算机组成架构  React底层架构      

当我们用生命周期函数来类比Hooks时,其实是用高抽象层级的事物来描述低抽象层级的事物。

动物 --> 哺乳动物 --> 牛 --> 奶牛

对于一个只见过奶牛,再没见过其他动物的人,你怎么向他解释哺乳动物是啥?

正是由于抽象层级的不对称,造成通过生命周期函数类比学习Hooks会遇到问题。

该怎么学Hooks

既然Hooks属于中等抽象层,离底层很近,那么更好的学习方式是通过底层向上学习。

祭出我们的三步公式:

  • 用户交互产生update

  • state = reconcile(update);

  • UI = commit(state);

对照公式,我们来讲解几个常见hook的工作流程:

useState

举个例子:

function App() {const [state, updateState] = useState(0);return <div onClick={() => updateState(state + 1)}></div>;
}

useState返回值数组包含:

  1. 保存的state

  2. 改变state的方法updateState

对照公式,state属于公式步骤2计算得出的:

  • state = reconcile(update);

此时视图还没有更新。

用户点击div触发updateState,对应公式步骤1:

  • 用户交互产生update

所以调用updateState能开启底层架构的三步运行流程。

reconcile计算出state后就会进入第三步:

  • UI = commit(state);

最终渲染视图。

useEffect

举个例子:

useEffect(doSomething, [xx, yy])

useEffect的回调函数doSomething在第三步执行完成后异步调用:

  • UI = commit(state);

所以在doSomething函数内部能获取到完成更新的视图。

第二个参数[xx, yy]作为依赖项,决定了doSomething是否会被调用。

useLayoutEffect

不同于useEffect在第三步执行完成后异步调用,useLayoutEffect会在第三步执行完UI操作后同步执行。

useRef

以上例子可以看到,useStateuseEffect分别在三步流程的不同步骤被触发,他们的触发时机是确定的。

那么这三个步骤如何交流呢?通过useRef

useState作用于第一、二步,useLayoutEffect作用于第三步,useEffect作用于第三步完成后。

使用useRef,就能达到在不同步骤间共享引用类型数据的目的。

可以看到,React为底层架构三步工作流程的每一步提供了对应的hook,同时提供了串联这三步工作流程的hook

开发者只需要根据业务需要,通过基础Hooks组装出自定义hook,就能在底层架构运行流程的各个时期运行逻辑。

自底向上学习是本末倒置么?

有同学会反驳:之前学React得学生命周期函数的执行时机,现在学Hooks得学底层架构运行流程。难道不是本末倒置,更复杂了么?

其实不然。我问你几个问题:

  1. componentWillReceiveProps为什么被标记为unsafe

  2. getDerivedStateFromProps用过么?

  3. this.setState是同步还是异步的?

这些和生命周期函数相关的问题一点都不简单!很多用了几年React的前端不一定回答的上。

作为高层次抽象,生命周期函数隐藏了太多实现细节。同时React又太灵活,不像Vue通过模版语言限制了开发者的操作。

结果就是:不同React开发者写出各种奇奇怪怪的ClassComponent

反观通过底层架构运行流程学习Hooks

  • 底层架构运行流程就是React的绝对真理,不会隐藏更多抽象

  • Hooks的写法规范限制了开发者的奇葩操作

这里唯一的问题,就是缺少一份从底层出发的文档。这也是官方要重写文档的初衷。

对于熟练使用React的开发者,在官方新文档出来前,可以参考React技术揭秘[1](点击阅读原文)学习。

这里再提供些其他视角聊Hooks的文章:

  • 理念层面:代数效应与Hooks[2]

  • 微观(代码)层面:所有常见Hooks的源码实现[3]

参考资料

[1]

React技术揭秘: https://react.iamkasong.com/

[2]

代数效应与Hooks: https://react.iamkasong.com/process/fiber-mental.html

[3]

所有常见Hooks的源码实现: https://react.iamkasong.com/hooks/structure.html

最近组建了一个江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你进群。



················· 若川出品 ·················

今日话题

vue-devtools工具中可以「根据组件直接打开对应文件」,多少人知道或者用过呢。

一个愿景是帮助5年内前端人走向前列的公众号

可加我个人微信 ruochuan12,长期交流学习

推荐阅读

我在阿里招前端,我该怎么帮你?(现在还能加我进模拟面试群)

如何拿下阿里巴巴 P6 的前端 Offer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

origin图上显示数据标签_Origin(Pro):寒假都结束了,这个图还是不会画?【数据绘图】...

寒假前给大家分享了一个图&#xff0c;大家要的教程来了。【数据绘图】好图分享&#xff1a;寒假&#xff1f;不存在的&#xff01;​mp.weixin.qq.com绘图思路&#xff1a;左侧起止时间&#xff1a;散点图&#xff0c;交换XY坐标轴&#xff1b;中间的连线为Drop Lines&#xf…

可以激发设计灵感的音乐_建立灵感库以激发您的创造力

可以激发设计灵感的音乐I often find a lot of inspiration from work I see while scrolling social media. Saving art or images that inspire you allows you to build a library of resources to draw from whenever you’re working on a project.在滚动社交媒体时&#…

CentOS服务器上部署 oracle10gr2

1、下载Centos系统 Linux 镜像文件。 推荐使用 CentOS5.4&#xff0c;下载地址&#xff1a;http://isoredirect.centos.org/centos/5/isos/i386/ 。这个是 32 位的 Linux 系统镜像安装文件&#xff0c;进入下载页面后&#xff0c;如果是 DVD 光盘安装&#xff0c;可以仅…

回顾:中网通讯网络公司CEO罗与曾作客新浪嘉宾聊天室

转载链接&#xff1a;http://tech.sina.com.cn/it/w/2001-11-09/91253.shtml 回顾&#xff1a;中网通讯网络公司CEO罗与曾作客新浪嘉宾聊天室 大家好&#xff01;   主持人 &#xff1a;各位网友&#xff0c;下午好&#xff0c;今天我们请到了中网通讯网络公司首席执行官罗…

form——验证器Validators

form表单最大的作用就是验证功能了&#xff0c;通过cleaned_data清洗&#xff0c;我们可以获取传来的值&#xff0c;通过参数、验证器、自定义验证方法&#xff0c;我们可以做到很多的验证。 验证器可用于在不同类型的字段之间重用验证逻辑。validators有自带的验证器&#xff…

若川知乎问答:做前端感觉很吃力怎么办?

前些日&#xff0c;我发了一篇推文《做前端感到越来越吃力了&#xff01;怎么办&#xff1f;》&#xff0c;虽然是推广&#xff0c;但阅读量却很高&#xff0c;推广标题我们大概率不能改&#xff0c;感觉骗了大家&#xff0c;掉粉挺多人。写稿的人可能就是看到了知乎这个问答。…

惠新宸php教程_惠新宸:首位国人加入PHP语言官方开发组

PHP开发组终于有了国人参与。最近&#xff0c; Laruence(真名惠新宸)加入了PHP语言官方开发组。 做PHP的同学一定很熟悉他了&#xff0c;他的博客风雪之隅(https://www.laruence.com/)发表了很多PHP源代码分析和扩展开发相关的文章。他使用PHP扩展开发的PHP框架Yaf&#xff0c;…

d3 制作条形图_停止制作常见的坏条形图的5个简单技巧

d3 制作条形图Bar charts were probably the first type of chart you were ever introduced to in first grade. Their simplicity makes them a standard in visualizing data, but it is its accessibility that leads visualizers to often be careless with bar charts.乙…

SVN之使用原则

以下是我起草的部门SVN规范里原则的一部分。文件提交时要求必须提交注释&#xff0c;注明相关修改信息&#xff0c;例如bug号、任务描述等。具体内容可采用约定或者设置的形式。你所提交的改变将体现给其他开发者&#xff0c;要明白提交的后果&#xff0c;提交之前要慎重。代码…

图解 React-router 源码

大家好&#xff0c;我是若川。欢迎加我微信 ruochuan12今天分享一篇react-router源码文章&#xff0c;深入理解路由的本质。微信预计阅读只需8分钟。点击下方卡片关注我&#xff0c;或者查看源码系列文章。阅读源码小 tips&#xff1a;从整体到细节&#xff0c;刚开始不要太拘泥…

青海西宁市大通县非洲猪瘟疫区解除封锁

中新网1月23日电 据农业农村部网站消息&#xff0c;农业农村部接到青海省农业农村厅报告&#xff0c;经评估验收合格&#xff0c;青海省西宁市大通县非洲猪瘟疫区解除封锁。 大通县非洲猪瘟疫情发生后&#xff0c;当地按照非洲猪瘟疫情应急预案和非洲猪瘟防治技术规范要求&…

回顾:中网饱经沧桑劫后余生 万平国回首艰辛历程

转载链接&#xff1a;http://tech.sina.com.cn/i/c/75586.shtml 回顾&#xff1a;中网饱经沧桑劫后余生 万平国回首艰辛历程 http://www.sina.com.cn 2001年07月12日 13:25 财经时报   “最早的聊天室是我们做的、最早的检索也是中网公司的、中网公司也是最早做电子商务的数…

android 辅助功能_辅助功能简介

android 辅助功能Accessibility may be more than a moral imperative to ensure products are inclusive of more people who already experience barriers in daily life — it has a very practical outcome, benefiting everyone including the person with the disability…

【columnstore】mariadb columnstore 数据迁移

通过cpimport传输迁移&#xff1a; 官方文档&#xff1a;https://mariadb.com/kb/en/lib...步骤&#xff1a; 1.导出库中表的表结构&#xff0c;不要数据 # mysqldump -h 127.0.0.1 -uroot -p -P 4066 --skip-lock-tables test -d > test.sql 2.nc将文件传输至目标机器192.…

我有一个梦想

我有一个梦想&#xff0c;做一名大师傅&#xff0c;快乐地下厨房。土豆在我刀下歌唱&#xff0c;茄子在我锅里跳舞。盘碗勺筷为我呐喊&#xff0c;油盐酱醋为我喝彩。 我有一个梦想&#xff0c;让土豆和茄子不再孤单&#xff0c;再加几个青椒&#xff0c;做一盘地三鲜。还要少放…

推荐几个前端大佬,真的厉害!

新的一年&#xff0c;推荐几个还在坚持输出的高质量前端公众号&#xff0c;你想要的&#xff1a;React/Vue/Node/工程化/面试经验等&#xff0c; 这里都有。不多说&#xff0c;直接看介绍。???? 程序员成长指北考拉&#xff0c;一个有趣且乐于分享的妹子&#xff0c;专注 N…

MySQL查询结果导出到文件

转载链接&#xff1a;http://eric-gcm.iteye.com/blog/1127734 选择某些行作为需要的数据 SELECT id,dbname FROM index into outfile "d://aaa.txt"; 一般大家都会用 “SELECT INTO OUTFIL”将查询结果导出到文件&#xff0c;但是这种方法不能覆盖或者添加到已经创建…

RawCode-本身就是实验性的8位类型

What if a type is created solely from the bit-representation of characters?如果仅根据字符的位表示形式创建类型怎么办&#xff1f; This question was the basis of creating this experimental type. The type no longer uses familiar characters. ‘A’ looks like …

2d访问冲突_Light | 基于环形分隔微镜阵列的高速随机访问轴向聚焦系统

撰稿 | OSANJU 刘 扬01导读近日&#xff0c;来自美国加州大学伯克利分校的Rikky Muller教授团队&#xff0c;在国际顶尖学术期刊《Light: Science & Applications》发表了题为“A micromirror array with annular partitioning for high-speed random-access axial focus…

编译出现ARM与THUMB冲突

问题&#xff1a; fatal error LNK1112: module machine type THUMB conflicts with target machine type ARM 解决方法&#xff1a; 在project-setting-linker-command line下&#xff0c;添加/machine:THUMB&#xff0c;如下&#xff1a; 转载于:https://www.cnblogs.com/xfd…