资讯专栏INFORMATION COLUMN

useEffect与useLayoutEffect

yibinnn / 2236人阅读

摘要:当某个无狀态组件要在某个阶段执行这些钩子,它会优先执行清理函数再执行初始函数。并且发现的函数会在最后才执行,它会晚于包含它的父函数。当目前还是实验性质,不排除会改变。不好用,不像那么明显可以与有狀态组件的生命周期钩子相对应。

React Hook让无狀态组件拥有了许多只有有狀态组件的能力,如自更新能力(setState,使用useState),访问ref(使用useRef或useImperativeMethods),访问context(使用useContext),使用更高级的setState设置(useReducer),及进行类似生命周期的阶段性方法(useEffect或useLayoutEffect)。

当然还有一些Hook,带来了一些新功能,如useCallback,这是对事件句柄进行缓存,useState的第二个返回值是dispatch,但是每次都是返回新的,使用useCallback,可以让它使用上次的函数。在虚拟DOM更新过程中,如果事件句柄相同,那么就不用每次都进行removeEventListner与addEventListner。最后就是useMemo,取得上次缓存的数据,它可以说是useCallback的另一种形式。

useState: setState 
useReducer: setState
useRef: ref
useImperativeMethods: ref
useContext: context
useCallback:可以对setState的优化
useMemo: useCallback的变形
useLayoutEffect:类似componentDidMount/Update, componentWillUnmount
useEffect: 类似于setState(state, cb)中的cb,总是在整个更新周期的最后才执行

从上面的描述来看useEffect的时期是非常晚,可以保证页面是稳定下来再做事情。但是useEffect与useLayoutEffect与有狀态组件的生命周期钩子又有一点不一样。

useEffect(function(){
  //dosomething
  return function(){
  //dosomething     
  }
 }, inputs)

useEffect与useLayoutEffect的第一个参数是一个函数(初始函数),这函数还会返回另一个清理用的函数(清理函数,在官方文档中没有明确的文字,都注释使用了clean up的字眼,就姑且这样叫)。当某个无狀态组件要在某个阶段执行这些钩子,它会优先执行清理函数再执行初始函数。




  
  

   
   
   



    

初次渲染的界面与日志

如果我们向input输入内容,就会发现它每次都会先进行 useEffect与useLayout的清理函数,再执行他们的初始函数。并且发现useEffect的函数会在最后才执行,它会晚于包含它的父函数。我们可以点击页面上的h1标签,就可以证明这一点。

点击h1会不断递增数字,到10时会销供Example这个无狀态组件与它的子组件Child。下面是数字到10时的界面与日志。

在我的迷你React框架中是这样实现这两个钩子

export function useEffect(create, inputs) {
    return dispatcher.useEffect(create, inputs, PASSIVE, "passive", "unpassive");
}
export function useLayoutEffect(create, inputs) {
    return dispatcher.useEffect(create, inputs, HOOK, "layout", "unlayout");
}
export var dispatcher = {
    //略...
    useEffect(create, inputs, EffectTag, createList, destoryList) {
        let fiber = getCurrentFiber();
        let cb = dispatcher.useCallbackOrMemo(create, inputs);
        if (fiber.effectTag % EffectTag) {
            fiber.effectTag *= EffectTag;
        }
        let updateQueue = fiber.updateQueue;
        let list = updateQueue[createList] ||  (updateQueue[createList] = []);
        updateQueue[destoryList] ||  (updateQueue[destoryList] = []);
        list.push(cb);
    },
    //略...
};

它们就是执行时机不一样。

当目前React Hook还是实验性质,不排除会改变。目前有9种钩子,其实之前有十种,useMutationEffect前不久已经完蛋了。useMemo与useCallback很相近,但觉得useMemo的使用场合很少,不知它会不会废掉。useEffect不好用,不像useLayoutEffect那么明显可以与有狀态组件的生命周期钩子相对应。useImperativeMethods这个名字起得不好,可能以后也会调整。当然这只是我的看法。

React Hook是一个很棒的设计,它其实是将有狀态组件的更新机制(setState/forceUpdate)的内部实现进行了更广泛的应用。当它的API稳定下来我会与大家分享它们更深层次的实现。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100330.html

相关文章

  • 十个案例学会 React Hooks

    摘要:在线传递给的是而不是,返回值即是想要透传的数据了。所以函数组件在每次渲染的时候如果有传递函数的话都会重渲染子组件。在学会使用React Hooks之前,可以先看一下相关原理学习React Hooks 前言 在 React 的世界中,有容器组件和 UI 组件之分,在 React Hooks 出现之前,UI 组件我们可以使用函数,无状态组件来展示 UI,而对于容器组件,函数组件就显得无能为力,我...

    williamwen1986 评论0 收藏0
  • 03. 该尝尝React Hook了。

    摘要:我们统一把这些操作称为副作用,或者简称为作用。尽可能使用标准的以避免阻塞视觉更新。大多数情况下,不需要同步地执行。返回的对象在组件的整个生命周期内保持不变。当对象内容发生变化时,并不会通知你。 Hook Hook 是 React 16.8.0 的新增特性。 Hook 使你在非 class 的情况下可以使用更多的 React 特性。Hook 不能在 class 组件中使用。 使用规则: ...

    cikenerd 评论0 收藏0
  • 如何用ahooks控制时机的hook?

      本篇主要和大家沟通关于ahooks ,我们可以理解为加深对 React hooks 的了解。  我们先说下关于抽象自定义 hooks。构建属于自己的 React hooks 工具库。  其实我们应该培养阅读学习源码的习惯,工具库是一个对源码阅读不错的选择。  注:本系列对 ahooks 的源码解析是基于v3.3.13。  现在就进入主题用ahooks 来封装 React要注意的时机?  Fun...

    3403771864 评论0 收藏0
  • react hooks 全面转换攻略(二) react本篇剩余 api

    摘要:不知道大家有没有使用过他的作用和中的差不多吧在需要读取的高度宽度的时候特别需要说到现在基本已经讲完了除了我将会放在篇中讲述相关文章全面转换攻略一本篇之全面转换攻略二本篇剩余全面转换攻略三全局存储解决方案 useCallback,useMemo 因为这两个 api 的作用是一样的,所以我放在一起讲; 语法: function useMemo(factory: () => T, deps:...

    molyzzx 评论0 收藏0
  • 解读useEvent显著降低Hooks负担的原生Hook

      想要做到就要有更多的学习,你知道为什么React不把他们设为默认方法#useEvent是一个刚刚提案的原生Hook,还处于RFC。现在我们就一起来讨论下  RFC:Request for Comments 提案应用的还十分广泛  我们先看看在没有 useEvent 会出现的情况:  functionChat(){   const[text,setText]=useState(''...

    3403771864 评论0 收藏0

发表评论

0条评论

yibinnn

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<