React Hooks 原理

Hooks的产生

1.组件状态:函数式组件被称为无状态组件,在没有hooks之前无法直接更新和管理状态。
2.生命周期:函数式组件没有像类式组件的生命周期方法,使用来模拟某些生命周期行为。
3.性能:函数式组件不需要维护实例对象,生命周期且没有内部状态,比类式组件具有更好的性能,更容易进行优化。

Hooks挂载数据的数据结构

在React16之前,直接递归遍历 VDOM即使用树状结构。当VDOM过大,频繁调用DOM API会出现耗时问题,且递归不能打断,同时具有性能问题。
后来引入了 fiber 架构(可中断 优先级调度 渐进式更新),将VDOM树转成fiber链表,再渲染 fiber。

Hooks存储数据

function组件初始化

初始化没有current树,完成一次组件更新后,会把当前workInProgress树赋值给current树。

renderWithHooks(
    null,                
    workInProgress,      
    Component, //函数组件本身         
    props,              
    context,             
    renderExpirationTime,
);

function组件更新

renderWithHooks(
//当前组件的Fiber节点。在函数组件或者自定义Hook组件的渲染过程中,current指向当前正在执行的Fiber节点。
    current, 
//当前组件的workInProgress Fiber节点。在渲染过程中复用current节点并在其上执行更新操作的Fiber节点,用于实现渐进式更新、中断和恢复工作等			
    workInProgress,
//当前被调用的渲染函数
    render,
//当前组件即将接收到的新的props属性值
    nextProps,
//当前组件的上下文对象
    context,
//当前渲染任务的到期时间
    renderExpirationTime,
);

hooks数据的存储

上述的workingInProgress节点的 memorizedState 就是保存 hooks 数据的地方,它是一个通过 next 串联的链表。
在这里插入图片描述
Hooks存取数据的地方就在这里,执行的时候各自在自己的memorizedState 上存取数据,完成各种逻辑,这就是 hooks 的原理。

memorizedState链表在何时创建

链表在第一次创建时会执行mountXxx,后面在调用只需要链表只需要updateXxx。所以链表只被创建一次,后续只有更新的操作。

比如第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState。
在这里插入图片描述

每个hooks api创建对应的 memorizedState 对象,然后用 next 串联起来
在这里插入图片描述

useRef的实现

我们从最简单的useRef入手,每一个hooks都有mountXxx 和 updateXxx 两个阶段,比如 ref 就是 mountRef 和 updateRef。
在这里插入图片描述
mountWorkInProgressHook 在上面提到过,用来创建并返回 memorizedState 链表,同理下面的updateWorkInProgressHook 用来更新。

将传进来的initialValue 放在了一个有 current 属性的对象然后放在 memorizedState 属性上。
后面update时,没有做任何处理,直接返回这个对象。

所以useRef 的功能就是:保存一个数据的引用,引用不可变。

useCallback的实现

useCallback 在 memorizedState 上放了一个数组,第一个元素是传入的回调函数,第二个是传入的 deps(同时对 deps 做了下 undefined 的处理)。

在这里插入图片描述
更新的时候把之前的memorizedState取出来,和新传入的deps 做对比,如果没变,就返回之前的回调函数,即prevState[0]。如果变了,就创建一个新的数组,第一个元素是传入的回调函数,第二个是传入的 deps。

所以,useCallback 的功能:实现函数的缓存,如果 deps 没变就不会创建新的函数,否则返回新传入的函数。

useMemo的实现

useMemo的实现与useCallback相似,只不过将useCallback中在 memorizedState存上放的数组的第一个元素的回调函数改为函数执行结果。
在这里插入图片描述
更新的时候也是取出之前的 memorizedState,和新传入的 deps 做对比,如果没变,就返回之前的值,即prevState[0]。如果变了,创建一个新的数组放在 memorizedState,第一个元素是新传入函数的执行结果,第二个元素是 deps。

所以,useMemo 的功能:实现函数执行结果的缓存,如果 deps 没变,就返回之前的结果,否则才会执行函数返回最新结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React HooksReact 16.8 版本引入的一种新特性,它是为了使函数组件能够拥有状态和其他 React 特性而设计的。 React Hooks原理基于两个核心概念:闭包和钩子函数。 1. 闭包:在函数组件内部,可以通过闭包的方式引用外部作用域的变量。React Hooks 利用了闭包的特性,使得可以在函数组件内部存储和更新状态。 2. 钩子函数:React Hooks 提供了一系列的钩子函数,如 useState、useEffect、useContext 等。这些钩子函数是预定义的特殊函数,可以在函数组件中使用,通过调用这些钩子函数,可以获取和操作组件的状态、副作用和上下文等。 当一个组件使用了 React HooksReact 在底层会创建一个与该组件实例相关联的 Fiber 对象,并在组件渲染时执行组件函数。在执行组件函数时,React 跟踪每个组件函数内部所有的钩子函数调用,并将其与该组件实例相关联。 当组件函数执行时,如果遇到 useState 钩子调用,React 会查找该钩子函数对应的状态值,并将其返回给组件函数。组件通过 useState 返回的状态值可以读取和更新组件的状态。 当组件函数执行完毕后,React 会将该组件的状态和副作用存储在 Fiber 对象中,并将 Fiber 对象添加到更新队列中。之后,React 会根据更新队列中的 Fiber 对象,对组件进行批量更新,实现页面的重新渲染。 通过这种方式,React Hooks 实现了函数组件的状态管理和副作用处理,使得开发者可以更方便地编写和维护 React 组件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值