跟着官方文档能学懂Hooks就怪了
时间:2023-03-19 01:12:03
科技观察
按照官方文档来学习如何理解Hooks,感觉有点不一样。比如componentWillReceiveProps对应的是哪些Hooks?迷茫,搜索一些Hooks原理层面的文章阅读。作为一个API,按照文档来调用不应该是简单可爱的吗?为什么Hooks这么难?React官方也发现了这个问题,当React要重写文档的时候,React是要基于Hooks来重写文档。这篇文章主要包括两个方面:解释Hooks难学的原因,给出学习Hooks的建议。用户与界面的交互可以看作是这个公式的不断执行。这个公式太简单了,没有解释状态(state)从何而来。让我们扩展它:conststate=reconcile(update);constUI=fn(状态);用户交互生成更新(update)更新计算当前应用程序通过reconcilestepstatefnmapsstatetoviewchange(UI)。我们给fn起个名字:commit:conststate=reconcile(update);constUI=提交(状态);那么在哪里生成更新?当然是来自于用户交互,比如:点击事件。因此,React的底层架构可以简化为三步:用户交互生成updatestate=reconcile(update);UI=提交(状态);了解了底层架构之后,我们再类比ClassComponent来看一下学习Hooks会带来的问题。生命周期函数的抽象层次我们已经有了一个完整的驱动视图更新的底层架构。开发者应该如何操作这个架构?可以类比计算机的抽象层次:高层:应用程序中层:操作系统底层:计算机组成架构对应React:高层:应用程序ClassComponent生命周期中层:操作系统介入架构API底层:计算机组合架构React底层架构可以看到,生命周期函数属于比较高的抽象层次。这样的设计也是为了让开发者更容易上手React。想象一个Vue2开发者想转入React技术栈,类比Vue的生命周期,学习React的生命周期就可以了。在Hooks到来之前这一切都很好,然而……Hooks的抽象级别Hooks属于中等抽象级别。也就是说,Hooks直接干预底层架构的运行过程。高层:应用程序中层:操作系统Hooks底层:计算机组成架构React低层架构当我们用生命周期函数来比较Hooks时,实际上是用高层抽象来描述低层抽象。Animals-->Mammals-->Cows-->Cows对于一个只见过牛而从未见过其他动物的人,你如何向他解释什么是哺乳动物?正是因为抽象层次的不对称,通过生命周期函数类比的LearningHooks才会遇到问题。如何学习Hooks由于Hooks属于中间抽象层,离底层很近,所以更好的学习方式是从底层学习。引入我们的三步公式:用户交互生成更新状态=reconcile(update);UI=提交(状态);对照公式,再解释一下几种常用hook的工作流程:useState例如:functionApp(){const[state,updateState]=useState(0);returnupdateState(state+1)}>
;}useState返回值数组包含:保存状态改变状态的方法updateState比较公式,状态属于第2步计算的公式:状态=调和(更新);此时,视图还没有更新。用户点击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不同,useEffect是在第三步执行完之后异步调用的。useLayoutEffect会在第三步完成UI操作后同步执行。从上面useRef的例子可以看出,useState和useEffect是在三步流程的不同步骤中触发的,它们的触发时机是确定的。那么这三个步骤是如何沟通的呢?通过useRef。useState作用于第一步和第二步,useLayoutEffect作用于第三步,useEffect作用于第三步完成。使用useRef,可以达到不同步骤之间共享引用类型数据的目的。可以看出,React为底层架构的三步工作流的每一步都提供了对应的hook,同时也提供了连接三步工作流的hook。开发者只需要根据业务需求,通过基础Hooks组装自定义的Hooks,就可以运行底层架构运行过程中各个阶段的逻辑。自下而上的学习是本末倒置吗?有同学会反驳:学React之前要学生命周期函数的执行时机,现在学Hooks要学底层架构运行流程。不是本末倒置更复杂吗?它不是。我问你几个问题:为什么componentWillReceiveProps被标记为不安全?你用过getDerivedStateFromProps吗?this.setState是同步的还是异步的?这些生命周期函数相关的题,一点都不简单!很多用了几年React的前端都不一定能答对。作为一种高级抽象,生命周期函数隐藏了太多的实现细节。同时React过于灵活,不像Vue通过模板语言来限制开发者的操作。结果是:不同的React开发者编写了各种奇怪的ClassComponents。另一方面,通过底层架构的运行过程来学习Hooks:底层架构的运行过程是React的绝对真理,不会隐藏更多抽象的Hooks。.这也是官方改写文档的初衷。对于熟练使用React的开发者,在官方新文档出来之前,可以参考React技术揭秘[1](点击阅读原文)进行学习。这里有一些从其他角度介绍Hooks的文章:从概念层面:代数效应与Hooks[2]从微观(代码)层面:所有常见Hooks的源码实现[3]