【React Hooks原理 - useEffect、useLayoutEffect】

介绍

在实际React Hooks项目中,我们需要在项目的不同阶段进行一些处理,比如在页面渲染之前进行dom操作、数据获取、第三方加载等。在Class Component中存在很多生命周期能让我们完成这个操作,但是在React Hooks没有所谓的生命周期,但是它提供了useEffect、useLayoutEffect来让我们进行不同阶段处理,下面就从源码角度来聊聊这两个Hooks。【源码地址

前提了解

同其他Hooks一样(useContext除外),在React18版本之后将其拆分为了mount、update两个函数,并由Dispatcher在不同阶段来执行不同函数。

// 挂载时
const HooksDispatcherOnMount: Dispatcher = {
   
   
  readContext,

  use,
  useCallback: mountCallback,
  useContext: readContext,
  useEffect: mountEffect,
  useImperativeHandle: mountImperativeHandle,
  useLayoutEffect: mountLayoutEffect,
  useInsertionEffect: mountInsertionEffect,
  useMemo: mountMemo,
  useReducer: mountReducer,
  useRef: mountRef,
  useState: mountState,
  useDebugValue: mountDebugValue,
  useDeferredValue: mountDeferredValue,
  useTransition: mountTransition,
  useSyncExternalStore: mountSyncExternalStore,
  useId: mountId,
};

// 更新时
const HooksDispatcherOnUpdate: Dispatcher = {
   
   
  readContext,

  use,
  useCallback: updateCallback,
  useContext: readContext,
  useEffect: updateEffect,
  useImperativeHandle: updateImperativeHandle,
  useInsertionEffect: updateInsertionEffect,
  useLayoutEffect: updateLayoutEffect,
  useMemo: updateMemo,
  useReducer: updateReducer,
  useRef: updateRef,
  useState: updateState,
  useDebugValue: updateDebugValue,
  useDeferredValue: updateDeferredValue,
  useTransition: updateTransition,
  useSyncExternalStore: updateSyncExternalStore,
  useId: updateId,
};

下面介绍主要涉及到两个文件中内容:

  • react/src/ReactHooks.js
    这个文件主要是定义暴露的给用户实际使用的Hooks,即我们在组件中通过import { useXXX } from 'react'引入的Hooks。
  • react-reconciler/src/ReactFiberHooks.js
    该文件主要是React内部真正执行的Hooks函数,内部将Hooks拆分为了mount、update两个函数,并通过Dispatcher在不同阶段进行分发如上所示

useEffect

由于React18对于Hooks进行了重新组织,将其拆分为了挂载时和更新时,所以我们也从这两方面入手介绍。

mount挂载时

源代码文件路径:react/src/ReactHooks.js

export function useEffect(
  create: () => (() => void) | void,
  deps: Array<mixed> | void | null,
): void {
   
   
  const dispatcher = resolveDispatcher();
  return dispatcher.useEffect(create, deps);
}

正如我们使用的那样,useEffect接受两个参数create、deps。然后通过dispatcher在不同阶段进行不同的处理即挂载时执行mountEffect,更新时执行updateEffect,通过上面的HooksDispatcherOnMount/HooksDispatcherOnUpdate映射。

React内部实现的Hooks代码都在react-reconciler/src/ReactFiberHooks.js文件下。(下面代码皆省略了DEV环境下的代码)

// react-reconciler/src/ReactFiberHooks.js
function mountEffect(
  create: () => (() => void) | void
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值