react Hooks(useEffect)实现原理 - 简单理解

useEffect

语法: useEffect(setup, dependencies?)
含义: useEffect 是一个 React Hook,它允许你 将组件与外部系统同步。

useEffect 源码简单理解

一、mountEffect 和 upadateEffect

useEffect 与其它 hooks 一样分为 mountEffect 和 upadateEffect 两个阶段

第一次执行 mountEffect
在这里插入图片描述
后面执行 upadateEffect
在这里插入图片描述
从代码中可以看出 mountEffect 和 upadateEffect 传参都是 函数 和 依赖数组,调用 mountEffectImplupdateEffectImpl
mountEffectImpl 和 updateEffectImpl 它们的四个入参一样。其中前面两个入参表示 tag 实现了指定的行为,具体可参考源码 ReactSideEffectTags.js 和 ReactHookEffectTags.js文件,暂时忽略。

二、mountEffectImpl 和 updateEffectImpl

mountEffectImpl

在这里插入图片描述
以上代码中可以看出 执行 pushEffect 并将返回结果记录在 hook的memoizedState上

updateEffectImpl

在这里插入图片描述
以下代码可以看出 当 currentHook 为空的时候,updateEffectImpl 的逻辑与 mountEffectImpl 的逻辑是一样。当 currentHook 不为空、依赖数组不为空时,判断依赖数组里的值是否有变化,若相等无变化则执行pushEffect。猜测这个时候的 hookFlags 指不执行这次 useEffect。

不管哪个阶段最终都执行 pushEffect 函数,那它是啥呢?

pushEffect

在这里插入图片描述
这个函数首先根据入参声明了一个新的 effect 并返回。它实际是一个循环链表

Effect = {
  tag: HookEffectTag, // 一个二进制数,它将决定 effect 的行为
  create: () => (() => void) | void, // 绘制后应该运行的回调
  inst: (() => void) | void, // 用于确定是否应销毁和重新创建 effect
  deps: Array<mixed> | null, // 决定重绘制后是否执行的 deps
  next: Effect, // 函数组件中定义的下一个 effect 的引用
};

componentUpdateQueue : 存储 Effect 的全局变量
判断 componentUpdateQueue 是否为空:

  1. componentUpdateQueue 空:与 mountEffect 逻辑类似,它会创建一个空的 componentUpdateQueue,它其实是 {lastEffect: null},之后将 componentUpdateQueue.lastEffect 指向 effect.next,其实就是存了一下 effect
  2. componentUpdateQueue 不为空:
    2.1 lastEffect 为空:这种情况是新的渲染阶段的第一个 useEffect,逻辑处理和 componentUpdateQueue 为空时一致
    2.2 lastEffect 不为空:这种情况意味着这个组件有多个 useEffect,是第二个及其之后的 useEffect 会走到的分支,将 lastEffect 指向下一个 effect

最后 returen effect

小结

以上就是 useEffect 源码的大致流程。表面上到这里就结束啦。
但不难发现,useEffect 的很多功能在上面代码并没有实现。还有以上代码中的 pushEffect 之后又有哪些逻辑呢?componentUpdateQueue 存储 Effect 之后会在哪里被用到?

饿了,先干饭去,后面接着总结。未完待续。。。

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: React Hooks中的useEffect是一个函数,用于在函数组件中处理副作用。它接收两个参数:一个函数和一个依赖数组。当依赖数组中的任何一个值发生变化时,useEffect中的函数就会被调用。这个函数可以用来执行一些副作用操作,比如发送网络请求、订阅事件、更新DOM等。在函数组件中使用useEffect可以替代类组件中的生命周期方法。 ### 回答2: React hooks是React 16.8版本新增的特性,可以让函数组件具有类组件的一些功能,其中包括useEffect这一HookuseEffect可以让我们在函数组件中实现类似于类组件中生命周期函数的效果。 useEffect接收两个参数,第一个参数是一个回调函数,第二个参数是一个数组。回调函数在组件每次渲染后都会执行,类似于componentDidUpdate函数。如果数组为空,回调函数仅在组件首次渲染时执行,类似于componentDidMount函数。如果数组不为空,回调函数仅在数组中的值有变化时执行,类似于shouldComponentUpdate函数。 useEffect可以用来处理一些副作用操作,比如数据的异步获取和更新、页面的滚动位置、事件的监听等等。在回调函数中进行的操作可能会影响到组件的状态、渲染等方面,所以我们需要使用useEffect来进行监控和管理。在回调函数中可以返回一个函数,这个函数在组件不再需要该效果时执行,可以用于取消监听等清理操作。 需要注意的是,useEffect在每次渲染后都会执行,如果回调函数中有一些操作比较耗时,则会对性能造成影响。我们可以使用useMemo、useCallback等Hook来优化这些操作的性能。此外,在数组中传递的参数需要谨慎选择,不恰当的选择可能会导致useEffect失效。 总之,useEffectReact hooks中非常重要的一个Hook,可以用来做很多副作用操作。只要我们掌握了useEffect的用法和注意事项,就能更好地管理和维护函数组件的状态和渲染。 ### 回答3: React Hooks是React16.8引入的新特性,大大简化了React组件的编写方式,其中useEffectReact Hooks中的一个非常重要的Hook,它允许我们在函数组件中执行任意一段副作用代码。 在React环境中,副作用通常涉及向服务器请求数据、处理DOM元素以及处理其他一些与UI渲染无关的操作。这些操作称为副作用,因为它们可能会对其他部分的应用程序的状态或行为产生影响,我们需要小心处理这些副作用。 使用useEffect可以在组件渲染时执行副作用,而且可以灵活地在组件生命周期中、或是在state或props发生变化时进行副作用的更新。 useEffect使用一个回调函数作为第一个参数,并在回调函数中定义需要执行的副作用代码。useEffect还可以有第二个参数,是一个数组,用于定义何时更新副作用的条件。如果第二个参数为空数组,那么副作用只会在组件挂载或卸载时执行。如果第二个参数包含依赖值,那么当依赖值有变化时,副作用也会被重新执行。 通过使用useEffect函数,我们可以在React函数组件中编写可以执行副作用代码的简洁股票。同时,也可以通过控制副作用代码的执行时机,避免副作用对应用程序产生不必要的影响。因此,useEffect已经成为React Hooks开发中的必不可少的一部分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值