保健励志美文体育育儿作文
投稿投诉
作文动态
热点娱乐
育儿情感
教程科技
体育养生
教案探索
美文旅游
财经日志
励志范文
论文时尚
保健游戏
护肤业界

ReactHooks的原理,有的简单有的不简单

  React是实现了组件的前端框架,它支持class和function两种形式的组件。
  class组件是通过继承模版类(Component、PureComponent)的方式开发新组件的,继承是class本身的特性,它支持设置state,会在state改变后重新渲染,可以重写一些父类的方法,这些方法会在React组件渲染的不同阶段调用,叫做生命周期函数。
  function组件不能做继承,因为function本来就没这个特性,所以是提供了一些api供函数使用,这些api会在内部的一个数据结构上挂载一些函数和值,并执行相应的逻辑,通过这种方式实现了state和类似class组件的生命周期函数的功能,这种api就叫做hooks。
  hooks挂载数据的数据结构叫做fiber。
  那什么是fiber呢?
  我们知道,React是通过jsx来描述界面结构的,会把jsx编译成renderfunction,然后执行renderfunction产生vdom:
  图片
  在v16之前的React里,是直接递归遍历vdom,通过domapi增删改dom的方式来渲染的。但当vdom过大,频繁调用domapi会比较耗时,而且递归又不能打断,所以有性能问题。
  图片
  后来就引入了fiber架构,先把vdom树转成fiber链表,然后再渲染fiber。
  图片
  vdom转fiber的过程叫做reconcile,是可打断的,React加入了schedule的机制在空闲时调度reconcile,reconcile的过程中会做diff,打上增删改的标记(effectTag),并把对应的dom创建好。然后就可以一次性把fiber渲染到dom,也就是commit。
  这个schdule、reconcile、commit的流程就是fiber架构。当然,对应的这个数据结构也叫fiber。
  (更多fiber的介绍可以看我之前的一篇文章:手写简易版React来彻底搞懂fiber架构)
  hooks就是通过把数据挂载到组件对应的fiber节点上来实现的。
  fiber节点是一个对象,hooks把数据挂载在哪个属性呢?
  我们可以debugger看下。
  准备这样一个函数组件(代码没啥具体含义,就是为了调试hooks):
  functionApp(){
  const〔name,setName〕useState(guang);
  useState(dong);
  consthandleruseCallback((evt){
  setName(dong);
  },〔1〕);
  useEffect((){
  console。log(1);
  });
  useRef(1);
  useMemo((){
  returnguanganddong;
  })
  return(
  {name}
  header
  );
  }
  在函数打个断点,运行到这个组件就会断住。
  我们看下调用栈:
  图片
  上一个函数是renderWithHooks,里面有个workingInProgress的对象就是当前的fiber节点:
  图片
  fiber节点的memorizedState就是保存hooks数据的地方。
  它是一个通过next串联的链表,展开看一下:
  图片
  链表一共六个元素,这和我们在function组件写的hooks不就对上了么:
  图片
  这就是hooks存取数据的地方,执行的时候各自在自己的那个memorizedState上存取数据,完成各种逻辑,这就是hooks的原理。
  这个memorizedState链表是什么时候创建的呢?
  好问题,确实有个链表创建的过程,也就是mountXxx。链表只需要创建一次,后面只需要update。
  所以第一次调用useState会执行mountState,后面再调用useState会执行updateState。
  图片
  图片
  我们先集中精力把mount搞明白。
  mountXxx是创建memorizedState链表的过程,每个hooksapi都是这样的:
  图片
  图片
  图片
  它的实现也很容易想到,就是创建对应的memorizedState对象,然后用next串联起来,也就是这段代码:
  图片
  当然,创建这样的数据结构还是为了使用的,每种hooksapi都有不同的使用这些memorizedState数据的逻辑,有的比较简单,比如useRef、useCallback、useMemo,有的没那么简单,比如useState、useEffect。
  为什么这么说呢?我们看下它们的实现再说吧。
  先看这几个简单的:
  useRef
  每个useXxx的hooks都有mountXxx和updateXxx两个阶段,比如ref就是mountRef和updateRef。
  它的代码是最简单的,只有这么几行:
  图片
  mountWorkInProgressHook刚才我们看过,就是创建并返回memorizedState链表的,同理,下面那个updateWorkInProgressHook是更新的。
  这些不用管,只要知道修改的是对应的memorizedState链表中的元素就行了。
  那ref在memorizedState上挂了什么呢?
  可以看到是把传进来的value包装了一个有current属性的对象,冻结了一下,然后放在memorizedState属性上。
  后面update的时候,没有做任何处理,直接返回这个对象。
  所以,useRef的功能就很容易猜到了:useRef可以保存一个数据的引用,这个引用不可变。
  这个hooks是最简单的hooks了,给我们一个地方存数据,我们也能轻易的实现useRef这个hooks。
  再来看个稍难点的:
  useCallback
  useCallback在memorizedState上放了一个数组,第一个元素是传入的回调函数,第二个是传入的deps(对deps做了下undefined的处理)。
  图片
  更新的时候把之前的那个memorizedState取出来,和新传入的deps做下对比,如果没变,那就返回之前的回调函数,也就是prevState〔0〕。
  如果变了,那就创建一个新的数组,第一个元素是传入的回调函数,第二个是传入的deps。
  所以,useCallback的功能也就呼之欲出了:useCallback可以实现函数的缓存,如果deps没变就不会创建新的,否则才会返回新传入的函数。
  这段逻辑其实也不难,就是多了个判断逻辑。
  再来看个和它差不多的:
  useMemo
  useMemo也在memorizedState上放了个数组,第一个元素是传入函数的执行结果,第二个元素是deps(对deps为undefined的情况做了下处理)。
  图片
  更新的时候也是取出之前的memorizedState,和新传入的deps做下对比,如果没变,就返回之前的值,也就是prevState〔0〕。
  如果变了,创建一个新的数组放在memorizedState,第一个元素是新传入函数的执行结果,第二个元素是deps。
  所以,useMemo的功能大家也能猜出来:useMemo可以实现函数执行结果的缓存,如果deps没变,就直接拿之前的,否则才会执行函数拿到最新结果返回。
  实现逻辑和useCallback大同小异。
  这三个hooks难么?给大家一个对象来存储数据,大家都能写出来,并不难。
  因为它们是没有别的依赖的,只是单纯的缓存了下值而已。而像useState、useEffect这些就复杂一些了,主要是因为需要调度。
  useState
  state改了之后是要触发更新的调度的,React有自己的调度逻辑,就是我们前面提到的fiber的schedule,所以需要dispatch一个action。
  (不展开讲,简单看一下)
  图片
  这里详细讲要涉及到调度,就先不展开了。
  useEffect
  同样的,effect传入的函数也是被React所调度的,当然,这里的调度不是fiber那个调度,而是单独的effect调度:
  (不展开讲,简单看一下)
  图片
  hooks负责把这些effect串联成一个updateQueue的链表,然后让React去调度执行。
  图片
  所以说,useState、useEffect这种hooks的实现是和fiber的空闲调度,effect的调度结合比较紧密的,实现上更复杂了一些。
  这里没有展开讲,因为这篇文章的目的是把hooks的主要原理理清楚,不会太深入细节。
  大家可能还听过自定义hooks的概念,那个是啥呢?
  其实就是个函数调用,没啥神奇的,我们可以把上面的hooks放到xxx函数里,然后在function组件里调用,对应的hook链表是一样的。
  图片
  只不过一般我们会使用React提供的eslint插件,lint了这些函数必须以use开头,但其实不用也没事,它们和普通的函数封装没有任何区别。
  总结
  React支持class和function两种形式的组件,class支持state属性和生命周期方法,而function组件也通过hooksapi实现了类似的功能。
  fiber架构是React在16以后引入的,之前是jsxrenderfunctionvdom然后直接递归渲染vdom,现在则是多了一步vdom转fiber的reconcile,在reconcile的过程中创建dom和做diff并打上增删改的effectTag,然后一次性commit。这个reconcile是可被打断的,可以调度,也就是fiber的schedule。
  hooks的实现就是基于fiber的,会在fiber节点上放一个链表,每个节点的memorizedState属性上存放了对应的数据,然后不同的hooksapi使用对应的数据来完成不同的功能。
  链表自然有个创建阶段,也就是mountXxx,之后就不需要再mount了,只需要update。所以每个useXx的实现其实都是分为了mountXxx和updateXxx两部分的。
  我们看了几个简单的hooks:useRef、useCallback、useMemo,它们只是对值做了缓存,逻辑比较纯粹,没有依赖React的调度。而useState会触发fiber的schedule,useEffect也有自己的调度逻辑。实现上相对复杂一些,我们没有继续深入。
  其实给我们一个对象来存取数据,实现useRef、useCallback、useMemo等hooks还是很简单的。对于需要调度的,则复杂一些。
  对于自定义的hooks,那个就是个函数调用,没有任何区别。(lint的规则不想遵守可以忽略)
  所有hooksapi都是基于fiber节点上的memorizedState链表来存取数据并完成各自的逻辑的。
  所以,hooks的原理简单么?只能说有的简单,有的不简单。

冬天太好了作文冬天来了,气温降到零摄氏度以下,经常刮着东北风,树叶抖落光了,树木上光秃秃的,就连流淌着的小溪也结了冰。蛇、青蛙、乌龟等都在冬眠,我们也都穿上了厚厚的棉衣。下雪了,地上一……1分钟带你快速了解区块链的技术模型架构区块链技术性并并不是一项单一的技术性,只是多种多样技术性融合自主创新的結果,其实质是一个弱管理中心的、自信赖的最底层构架技术性。区块链技术性实体模型由上而下包含数据信息层……Tiobe最新8月编程语言排行出炉!有哪些新变化?Tiobe编程语言排行榜一月一更新8月数据已新鲜出炉下面一起来看看有哪些变化吧8月Tiobe编程排行前20名历史变化趋势年度最佳编程语言2021年……写给老师的几条意见写给老师的几条意见现在老师十分的多,而且很会教育。但有几点老师是错误的,要知那几点?请往下看。第一点:老师不注重孩子心情。每位老师孩子有些错误,就严厉批评。这使有些……妈妈的爱六年级英语作文在平凡的学习、工作、生活中,大家都不可避免地会接触到作文吧,写作文是培养人们的观察力、联想力、想象力、思考力和记忆力的。重要手段。相信很多朋友都对写作文感到非常苦恼吧,以下是小……落汤激六年级作文一个素不相识的人,让我从一个可怜的落汤鸡,有了落汤激。题记这两天,随着天气渐渐变冷,空中飘起了雪花,不仅让我又想起了几个月前的一件事。那一天,天空一直是阴沉沉……关于绊脚石的作文800字导语:世上有成功,也有失败,然而事业难成易败的原因。下面小编分享的关于绊脚石的作文800字。关于绊脚石的作文800字一世上有成功,也有失败,然而事业难成易败的原因是什么呢……脱离华为也没用?禁售令或再次升级,荣耀也不能幸免?为了避开禁售令的限制,华为在去年年底将荣耀品牌剥离出去,荣耀也因此成为一个独立的品牌;独立之后的荣耀在很长一段时间都没有推出智能手机,但由于接手荣耀的大都是渠道商,荣耀品牌在渠……中学生优秀作文600字节约用水这并不是危言耸听,要是我们不节约水资源,总有一天会无水可用。今天小编就来分享中学生优秀作文600字:节约用水,请各位读者好好欣赏和借鉴。中学生优秀作文600字:节约用水(……女员工遭高管侵害,不是阿里的话关注度不会这么高,酒店应当反省阿里巴巴女员工自称在山东出差时,酒桌上遭客户猥亵,事后遭受领导多次性侵!这一件事,可以说是爆炸点太多太多了,在说这件事情之前,先一起来回忆一下,就在几天前,一名微博的女网……唯品会唯内购退货上门取件是真的吗?唯内购最大团队长刘教授解答唯内购上门取件须知退换货上门取件服务,是唯内购为提高店家售后管理效率、提升消费者购物体验而引入的特色服务,也是丢损必赔等增值服务的体现。在售后详情页的寄送方式处选择上门取……名企龌龊阿里高管一晚四度性侵下属上海电气总裁一周两度自杀就在前几天,传出了一条大好消息:在世界500强的最新榜单上,中国企业上榜143家,再次超过美国(122家),蝉联榜首。阿里巴巴从去年的132位上升至63位,完全属于飞步快……
关于平安夜的作文今天是平安夜今天是平安夜,可是,上天不保佑我们,阴沉沉的天气,乌云密布,不一会儿就下起了小雨。但是,蒙蒙细雨还是经不住人们的心情。晚上,我为了买一本书法字帖,就兴致勃勃地来到马路上。……给四川小伙伴的一封信小学四年级作文四川的小伙伴们:你们好!我听说你们那里发生了强烈的地震还丧失了一些亲人,一些朋友。有些还在人世,有些已经离开人世。我相信你们一定会勇敢的面对现实的。地震能摧毁你们的……人教版高中第六册三单元作文我最尊敬的人一双长满老茧的手,一张饱经风霜的脸,一个苍桑而熟悉的背影,这就是我的母亲,这就是我最尊敬的人。母亲是一位心灵手巧的农家妇女,她用她那双智慧勤劳的双手给我们撑起了一个幸福温……工信部完善新一轮新能源汽车下乡活动启动公共领域车辆全面电动化品玩4月19日讯,工业和信息化部新闻发言人、运行监测协调局局长罗俊杰在发布会上表示,将推进制造业十四五规划重大工程和项目的加快落地实施,支持一批节能降碳重大技术改造项目,引导基……我的家乡作文模板三份引导语:家乡是让在外游子最为牵挂的地方之一,亦相信大家对于自己的家乡都不陌生,那么要怎样写一篇以我的家乡为题的作文呢?接下来是小编为你带来收集整理的文章,欢迎阅读!我的家乡作文……这样的人让人佩服作文优秀生活中总是有着一种人让我们觉得敬佩,令人心生敬意。yuwenmi小编整理了相关的范文,欢迎欣赏与借鉴。这样的人让人佩服作文一:去年暑假的一天,一个小砖匠来帮我们家装修浴室……中国电信公司一季度营收1196亿元,增长11。9新京报贝壳财经讯(记者许诺)4月20日盘后,中国电信在港交所发布了2022年一季度财报。财报显示,今年一季度,公司经营收入为人民币1196。29亿元,较去年同期增长11。9,股……读伤仲永有感《伤仲永》讲述了:有一个叫方仲永的小孩,天资聪明,五岁就能作诗。可他出了名后,他的爸爸就不再让他学习了,带他去全县各处题诗挣钱。由于方仲永没有再学习,最后一事无成,成为一个普通……废材逆天狂妄腹黑六小姐001什么鬼?穿越?!痛痛痛!艾玛!我不是死了吗?痛个毛线哦?紫颜云萱刚刚醒,只有一个感觉:痛。ldquo;紫颜芬,打死这个小贱人!勾引奕哥哥,真不要脸!rd……我考好了六年级作文天哪!今天就要发成绩了!我突然觉得世界暗淡无光,好像天上下一秒就要飞下来一张仅有六十分的卷子。在上学的路上,小鸟在叫着,像在说:唉这孩子有可能成绩不怎么样呀!路上的喇叭声像是在……可爱的花生作文500字一个小房子,里面红窗帘,窗帘里有个胖娃娃,大家猜猜它是谁?回答正确,它就是人见人爱,花见花开的花生。今天妈妈买回来一大袋花生,要知道花生可是我的最爱呀,花生小姐们像太阳奶……友谊作文500字5篇关于友谊的作文500字(一)友谊,是人类最纯洁的感情,是天空中两颗星的邂逅,即使匆匆擦身而过,也会闪出明亮的光华;友谊,是心海中两叶小舟的偶遇,虽不会永远相伴,却能彼此留……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网