react Hooks(useRef、useMemo、useCallback)实现原理

news2024/12/23 9:13:10

Fiber

上篇文章fiber简单理解记录了react fiber架构,Hooks是基于fiber链表来实现的。阅读以下内容时建议先了解react fiber。

jsx -> render function -> vdom -> fiber树 -> dom

vdom 转 fiber 的过程称为 recocile。diff算法就是在recocile这个过程中实现。

经过 reconcile 生成新的fiber树。这时候还没有处理副作用(hooks、生命周期等),这些会在reconcile 结束之后处理。

react渲染分为两个阶段:render 和 commit。

render:指 vdom -> fiber 的过程
commit: 指 fiber -> dom 具体操作dom以及执行副作用函数的过程。其包含了三个小阶段:before mutation、mutation(真实操作dom)、 layout。

Hooks

hooks是在哪个阶段处理呢? commit fiber -> dom
hooks的数据保存在哪里呢? fiber 的 memoizedState 链表上存取数据。
是什么时候构造这个链表呢? 在第一次调用 useXxx 的时候

一、 useRef

语法:const refContainer = useRef(initialValue);
作用:useRef 返回一个可变的 ref 对象,其内部只有一个 current 属性被初始化为传入的参数(initialValue)

useRef是怎么实现的呢?

第一次调用 useRef 会走到 mountRef:
在这里插入图片描述
在 mountRef 里可以看到它创建了一个 hook 节点,然后设置了 memoizedState 属性为有 current 属性的对象,也就是 ref 对象。

//以下代码为源码中相关代码缩写,详细过程请看源码
function mountRef<T>(initialValue: T): {current: T} {
  const hook = mountWorkInProgressHook();
  const ref = {current: initialValue};
  hook.memoizedState = ref;
  return ref
}

mountWorkInProgressHook函数用来具体创建 hook 链表
在这里插入图片描述
其第一个节点挂在 fiber 的 memoizedState 属性上,后面的挂在上个节点的 next 属性上。

第二次调用 useRef 会走到 updateRef:
在这里插入图片描述
这里的 updateRef 就是取出 hook 的 momorizedState 的值直接返回了:
在这里插入图片描述
所以 useRef 的返回的 ref 对象始终是最开始那个。

二、useMemo

语法: const cachedValue = useMemo(calculateValue, dependencies)
作用: 它在每次重新渲染的时候能够缓存计算的结果。当依赖的值不变时始终返回之前的值,依赖值变化时创建新的值

那它是怎么实现的呢?

useMemo 同样也是分为 mountMemo 和 updateMemo 两个阶段。

第一次调用 useMemo 会执行 mountMemo
在这里插入图片描述
创建 hook, 执行传入的 nextCreate 函数,把值设置到 hook.memoizedState 属性上。

更新数据时执行的是 updateMemo
在这里插入图片描述
在 updateMemo 的实现中,有一个关键函数 areHookInputsEqual,它用于比较依赖项数组:
如果依赖数组都没变,那就返回之前的值,否则创建新的值更新到 hook.memoizedState。

三、useCallback

语法: const cachedFn = useCallback(fn, dependencies)
作用: 是一个允许你在多次渲染中缓存函数的 React Hook。当依赖的值变化时才执行fn。

那它是怎么实现的呢?

useCallback 同样也是分为 mountCallback 和 updateCallback 两个阶段。

第一次调用 mountCallback
在这里插入图片描述
第二次及以后updateCallback
在这里插入图片描述
其实现和 useMemo 基本一致。其原理都是通过areHookInputsEqual 函数进行依赖项比对,区别在于 useMemo 返回是新数据对象,而 useCallback 返回是回调函数

小结: hook 的数据存放在 fiber 的 memoizedState 属性的链表上,每个 hook 对应一个节点,第一次执行 useXxx 的 hook 会走 mountXxx 的逻辑来创建 hook 链表,之后会走 updateXxx 的逻辑。

当然,前面的 useRef、useCallback、useMemo 都相对简单。但 useEffect 和 useState 就相对复杂了。考虑到篇幅问题,useEffect 详情记录在写一篇文章中。

参考来源:
reacthooks源码
react中文文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1303887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国内外聊天AI大比拼,你知道几个?一键了解最火聊天AI应用!

国内类ChatGPT的AI工具一网打尽 2022年&#xff0c;是一个不平凡的一年。ChatGPT迅速崭露头角&#xff0c;成为备受瞩目的热门话题。特别是在OpenAI发布了基于GPT-3.5模型的ChatGPT版本后&#xff0c;这一产品因其卓越的对话能力和广泛的应用潜力&#xff0c;很快引起了大众的…

GoWeb开发框架gin-基础路由使用

文章目录 1.安装并写一个demo2.配置GoLang热加载脚手架3.配合net/http使用完整示例4.返回值4.1String返回值4.2Json返回值4.3struct结构体返回值4.4jsonp返回值4.5XML返回值 5.接收前端传过来的参数5.1get请求传值5.2form表单传值5.3接收结构体5.4路由地址传参 6.完整代码 1.安…

nodejs+vue+微信小程序+python+PHP基于spark的酒店管理系统-计算机毕业设计推荐

通过管理系统进行全面的线上管理。管理者可以通过基于spark的酒店管理系统&#xff0c;全面掌握酒店客房的各项状态&#xff0c;会员通过系统查询酒店客房信息&#xff0c;在线预定。 酒店作为旅游过程必须的设施&#xff0c;也逐渐需需要进行信息化管理&#xff0c;把酒店类型…

python 爬虫 m3u8 视频文件 加密解密 整合mp4

文章目录 一、完整代码二、视频分析1. 认识m3u8文件2. 获取密钥&#xff0c;构建解密器3. 下载ts文件4. 合并ts文件为mp4 三、总结 一、完整代码 完整代码如下&#xff1a; import requests import re import os from tqdm import tqdm from Crypto.Cipher import AES# 创建临…

油田中控室与32台碳储罐之间数据无线传输

二氧化碳强化石油开采技术&#xff0c;须先深入了解石油储层的地质特征和二氧化碳的作用机制。现场有8辆二氧化碳罐装车&#xff0c;每辆罐车上有4台液态二氧化碳储罐&#xff0c;每台罐的尾部都装有一台西门子S7-200 smart PLC。在注入二氧化碳的过程中&#xff0c;中控室S7-1…

json.loads和eval 速度对比

json.loads和eval 速度对比 代码1结果图代码2参考地址 代码1 import json import time import pandas as pddata_sets pd.read_pickle("val_token_id.pandas_pickle") data_sets[str(i) for i in data_sets] starttime.time() [json.loads(i) for i in data_sets] …

企业使用APP自动化测试工具的重要因素

随着移动应用市场的蓬勃发展&#xff0c;企业对高质量、高效率的软件交付提出了更高的要求。在这个背景下&#xff0c;APP自动化测试工具成为了企业不可或缺的一部分。以下是企业采用APP自动化测试工具的关键因素&#xff1a; 1. 快速且可重复的测试执行 自动化测试工具能够快速…

好看的早上问候语早安图片,今天最新唯美温馨祝福语

1、天气冷了&#xff0c;情谊不凉&#xff0c;树叶黄了&#xff0c;思念不忘&#xff0c;问候像一杯热茶&#xff0c;让人暖心&#xff01;祝愿我们与健康平安同行&#xff01;朋友们&#xff0c;大家早上好&#xff01; 2、多一个人牵挂是一种幸福&#xff1b;多一个人相知是一…

【分治】循环赛日程表Python实现

文章目录 [toc]问题描述分治算法示例Python实现 无运动员数量约束循环赛日程表算法示例Python实现 问题描述 设有 n 2 k n 2^{k} n2k个运动员要进行网球循环赛&#xff0c;设计一个满足以下要求的比赛日程表 每个选手必须与其他 n − 1 n - 1 n−1个选手各赛一次每个选手一天…

vue elementui点击按钮新增输入框(点多少次就新增多少个输入框,无限新增)

效果如图&#xff1a; 核心代码&#xff1a; <div v-for"(item,index) in arrayData" :key"item.id">//上面这个是关键代码&#xff0c;所有思路靠这个打通<el-inputtype"input" //除了输入框&#xff0c;还有textarea等placeholder&…

编程实战:自己编写HTTP服务器(系列5:执行后台命令)

系列入口&#xff1a;编程实战&#xff1a;自己编写HTTP服务器&#xff08;系列1&#xff1a;概述和应答&#xff09;-CSDN博客 本文介绍执行后台命令的shell.asp的实现。 目录 一、概述 二、主体代码 三、详解 3.1 参数 一、概述 这个功能就相当于一个终端&#xff0c;不…

商城免费搭建之java商城 java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c 鸿鹄云商

鸿鹄云商 SAAS云产品概述 【SAAS云平台】打造全行业全渠道全场景的SaaS产品&#xff0c;为店铺经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多…

MySQL:从MySQL看主从架构高可用性实现

目录 1 主备延迟 1.1 主备延迟 1.2 主备延迟的来源 1.2.1 主备机性能有差距 1.2.2 备库压力大 1.2.3 大事务 1.3 主备延迟的排查思路 3&#xff09;查看MySQL状态 2 主备切换策略 2.1 可靠性优先策略 2.2 可用性优先策略 2.3 常见切换技术 从进入互联网时代开始&a…

Linux之进程(三)(环境变量)

目录 一、基本概念 二、环境变量 1、PATH 2、HOME 3、SHELL 三、环境变量参数 四、argc和argv 一、基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。如&#xff1a;临时文件夹位置和系统文件夹位置等。环境变量通常…

【软考】信息系统项目管理师论文方向猜想

报喜不报忧&#xff0c;每天都在为鸡零狗碎推诿扯皮&#xff0c;属实是有辱师门。 通过软考&#xff0c;目前算是真正有意义的事情。 虽然都说高项的论文是个玄学&#xff0c;但是道听途说了一些通关感想还是蛮有启发的。 文件要求 参考了一份广西省高级工程师评审的文件&am…

【C语言】二分查找(详解)

&#x1f3a5; 岁月失语唯石能言的个人主页 &#x1f525;个人栏专&#xff1a;秒懂C语言 ⭐若在许我少年时&#xff0c;一两黄金一两风 一、二分查找的思路 二分查找也叫折半查找&#xff0c;二分查找针对的是一个有序的数据集合&#xff0c;每次都通过跟区间的…

C# 图解教程 第5版 —— 第18章 泛型

文章目录 18.1 什么是泛型18.2 C# 中的泛型18.3 泛型类18.3.1 声明泛型类18.3.2 创建构造类型18.3.3 创建变量和实例18.3.4 使用泛型的示例18.3.5 比较泛型和非泛型栈 18.4 类型参数的约束18.4.1 Where 子句18.4.2 约束类型和次序 18.5 泛型方法18.5.1 声明泛型方法18.5.2 调用…

宿舍智能电能表预付费系统的费控策略及应用

安科瑞电气股份有限公司 上海嘉定 201801 摘要:基于智能电能表的预付费系统平台可以实现对预付费客户的适时算费、远程费控和服务。预付费系统的费控策略包括算费子策略、催费预警提醒子策略、欠费停电子策略,介绍3个子策略的制定原则、设计流程,并以示例说明策略的实现方式,通…

每日一博 - Cache Miss Attack

文章目录 概述解决思路缓存空值键并设置短期 TTL&#xff08;生存时间&#xff09;使用布隆过滤器 伪代码1. 缓存空值键并设置短期 TTLa. 缓存空值键b. 设置短期 TTL 2. 使用布隆过滤器a. 集成布隆过滤器b. 查询布隆过滤器 进一步优化系统性能的建议 概述 在缓存管理中&#x…

(C++)VS下sizeof(string(““))与linux-g++下sizeof(string(““))大小区别及原因剖析

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 说明 博主是x86平台&#xff0c;所以下面的结果是28&#xff1b;x64平台下是40&#xff0c;size_t变了&#xff0c;由int变long long。 接下来我们先来介绍 vs 下string的数据结构 我们可以看到有一个_Buf数组&#xff0c;…