React UseMemo源码分析

devtools/2024/10/19 4:20:41/

useMemo

useMemo 是 React 提供的内置 Hooks,主要作用就是缓存,如果依赖项没有变化,Memo 方法不会再次执行,计算量比较高的方法可以使用,从而提高用户体验。本文将通过一个例子跟踪 Memo 的创建、更新流程。

App.js

//App.js
import { useState } from 'react';
import { createTodos } from './utils.js';
import TodoList from './TodoList.js';const todos = createTodos();export default function App() {const [tab, setTab] = useState('all');const [isDark, setIsDark] = useState(false);return (<><button onClick={() => setTab('all')}>All</button><button onClick={() => setTab('active')}>Active</button><button onClick={() => setTab('completed')}>Completed</button><br /><label><inputtype="checkbox"checked={isDark}onChange={e => setIsDark(e.target.checked)}/>Dark mode</label><hr /><TodoListtodos={todos}tab={tab}theme={isDark ? 'dark' : 'light'}/></>);
}
//TodoList.js
import List from './List.js';
import { filterTodos } from './utils.js'
import {useMemo} from 'react'export default function TodoList({ todos, theme, tab }) {const visibleTodos = useMemo(() => filterTodos(todos, tab),[todos, tab]);return (<div className={theme}><p><b>Note: <code>List</code> is artificially slowed down!</b></p><List items={visibleTodos} /></div>);
}

/**  filename List.js* */
import { memo } from 'react';const List = memo(function List({ items }) {console.log('[ARTIFICIALLY SLOW] Rendering <List /> with ' + items.length + ' items');let startTime = performance.now();while (performance.now() - startTime < 500) {// Do nothing for 500 ms to emulate extremely slow code}return (<ul>{items.map(item => (<li key={item.id}>{item.completed ?<s>{item.text}</s> :item.text}</li>))}</ul>);
});export default List;
/**  filename utils.js* */
export function createTodos() {const todos = [];for (let i = 0; i < 50; i++) {todos.push({id: i,text: "Todo " + (i + 1),completed: Math.random() > 0.5});}return todos;}export function filterTodos(todos, tab) {return todos.filter(todo => {if (tab === 'all') {return true;} else if (tab === 'active') {return !todo.completed;} else if (tab === 'completed') {return todo.completed;}});}

初始化

首次进入,运行并绑定结果。
在这里插入图片描述
进入绑定逻辑,可以看到 nextCreate 在这里运行,返回结果和依赖项。
在这里插入图片描述

更新

点击 active 按钮,进入memo 更新流程
在这里插入图片描述
如果依赖没有变化,直接返回,有变化运行函数并更新。
在这里插入图片描述
Memo 的值也是存在 FiberNode 的memoizedState 属性中

在这里插入图片描述

总结

Memo 的原理是根据依赖项变化判断是否更新,数据存在 FiberNode 上进行集中控制,更新时从组件的 FiberNode 上获取上次记录的状态并与本次的状态进行比较,并根据比较结果进行相应的处理。


http://www.ppmy.cn/devtools/46799.html

相关文章

红米K70 Pro:24G+1TB也降500元,值得入手

目录 一、外观设计&#xff1a;精致与实用并重 二、处理器&#xff1a;性能巅峰的骁龙8 Gen3 三、屏幕方面&#xff1a;沉浸式的视觉盛宴 四、拍照方面&#xff1a;记录生活的每一刻 五、存储方面&#xff1a;海量存储无忧 六、续航方面 红米 K70 Pro 作为Redmi系列中的高…

前端面试题日常练-day54 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末 1. 在PHP中&#xff0c;以下哪个函数用于将一个字符串转换为日期时间对象&#xff1f; a) date() b) strtotime() c) datetime() d) time() 2. PHP中的超全局变量$_COOKIE用于存储什么类型的数据&a…

【头歌】计算机网络DHCP服务器配置第四关配置路由器子接口答案

头歌计算机网络DHCP服务器配置第四关配置路由器子接口操作步骤 任务描述 本关任务&#xff1a;配置路由器的子接口。 操作要求 在第一关的拓扑图的基础上&#xff0c;配置路由器及 PC 机&#xff0c;具体要求如下&#xff1a; 1、打开路由器物理接口 F0/0 &#xff1b; 2、配置…

STM32作业实现(五)温湿度传感器dht11

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

【Linux】Linux工具——gdb

1. gdb 概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许&#xff0c;各位比较喜欢那种图形界面方式的&#xff0c;像VC、BCB等IDE的调试&#xff0c;但如果你是在 UNIX平台下做软件&#xff0c;你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能…

java web爬虫

目录 读取本地文件 从网站读取文件 java爬虫 总结 读取本地文件 import java.io.File; import java.io.PrintWriter; import java.util.Scanner;public class ReplaceText {public static void main() throws Ex

面试 Redis 八股文十问十答第二期

面试 Redis 八股文十问十答第二期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;redis 一般都用在什么场景…

安徽某高校数据挖掘作业6

1 根据附件中year文件&#xff0c;编辑Python程序绘制年销售总额分布条形图和年净利润分布条形图&#xff0c;附Python程序和图像。 2 根据附件中quarter和quarter_b文件&#xff0c;编辑Python程序绘制2018—2020年销售额和净利润折线图&#xff0c;附Python程序和图像。 3 …