Day8:浅谈useMemo

news2024/11/25 4:31:53

「目标」: 持续输出!每日分享关于web前端常见知识、面试题、性能优化、新技术等方面的内容。

Day8-今日话题

useMemo 是 React 中一个有力的性能优化Hook。可从「用法」「工作原理」「作用」「优缺点」「使用场景」「使用注意点」进行学习、复习。

拿vue作比较的话,功能可以类比成vue的计算属性「computed」,都是因为依赖项发生变化而进行重新计算。

1. 用法

useMemo 是 React 中的一个 Hook,用于缓存计算结果,以减少不必要的计算和渲染。它接受两个参数:

  • 一个函数,用于计算需要缓存的值。
  • 一个依赖数组,包含了在数组中列出的变量发生变化时才重新计算值,可以为空数组或包含多个依赖。
const memoizedValue = useMemo(() => computeExpensiveValue(dep1, dep2), [dep1, dep2]);

2. 工作原理

useMemo 的工作原理涉及到 React 的渲染过程和依赖数组的比较,下面详细介绍其工作原理:

  1. 「组件的初始渲染和依赖项变化时」
  • 当一个组件首次渲染时或其依赖项发生变化时,React 会执行组件函数内的所有代码,包括 useMemo
  • useMemo 中,第一个参数是一个计算函数。React 调用这个函数,计算并返回一个值,同时将这个值存储在内部。
  • React 还会将依赖数组( useMemo 的第二个参数)的内容记录下来。
  1. 「比较依赖项」
  • 当组件重新渲染时,React 会再次执行组件函数,包括 useMemo
  • 在这个阶段,React会比较当前的依赖数组和上一次渲染时存储的依赖数组。
  1. 「重新计算或复用」
  • 如果当前的依赖数组和上一次的依赖数组完全相同(即每个元素都严格相等),React 会认为依赖项没有变化,不会重新计算 useMemo 的结果。
  • 如果当前的依赖数组和上一次的依赖数组不相等,React 将重新调用 useMemo 中的计算函数,计算并返回新的值。
  • 如果依赖数组为空( []),则 useMemo 的结果只会在组件首次渲染时计算一次,并且永远不会重新计算。
  1. 「返回计算结果」
  • 无论是重新计算还是复用, useMemo 的最终结果都将返回给组件,可以在组件中使用。

这个工作原理确保了 useMemo 只在其依赖项发生变化时才会重新计算,从而有效地避免了不必要的计算和渲染。这对于优化性能和确保组件的一致性非常重要。

需要注意的是,useMemo 返回的是缓存的值,而不是一个函数。如果需要缓存一个函数,可以使用 useCallback。此外,useMemo 的依赖数组应该包含所有在计算函数中使用的变量,以确保在依赖项变化时重新计算。

3. 作用

  • 「性能优化」useMemo 可以用于缓存昂贵的计算,避免不必要的重新计算,从而提高性能。
  • 「避免不必要的渲染」:通过将 useMemo 的结果用作子组件的 prop,可以避免子组件在不必要的情况下重新渲染。
  • 「缓存引用类型」:可以缓存引用类型(如对象或数组),以避免在每次渲染时都创建新的引用。

4. 优点

  • 「性能优化」:最明显的优点是帮助优化性能,避免不必要的计算和渲染。
  • 「可读性」:通过明确指定依赖,代码变得更加可读和可维护。

5. 缺点

  • 「滥用可能导致性能问题」:过度使用 useMemo 可能会导致性能问题,因为它可能导致不必要的内存占用。应该谨慎选择使用它,只在需要缓存计算结果时才使用。
  • 「复杂性增加」:如果依赖数组包含多个变量,维护这些依赖可能会增加代码复杂性。

6. 使用场景

  • 「计算结果昂贵」:用于缓存计算成本高昂的值,例如数学计算、数据筛选、数据转换等。
  • 「避免不必要的渲染」:将 useMemo 的结果用作子组件的 prop,以确保子组件只在必要时重新渲染。
  • 「缓存引用类型」:当需要在多次渲染之间保持相同的引用类型时,可以使用 useMemo

通俗来讲就是说,当前组件或者当前组件所在的父组件修改状态(state)时,我们不想让其 render 函数中的某个节点或者自身因为不相关的状态变化而去重新渲染造成性能上的浪费,可以使用useMemo来解决这个问题。

7.使用注意点

使用 useMemo 时需要注意以下几个重要的方面:

  1. 「性能优化的平衡」:不要滥用 useMemo。只有在有昂贵的计算或大型引用类型传递给子组件时,才考虑使用它。过度使用 useMemo 可能会导致不必要的复杂性和性能问题。

  2. 「正确选择依赖项」:确保依赖数组包含了所有在计算函数中使用的变量。如果忘记包含某个依赖,可能导致缓存的值不会在依赖变化时重新计算。

  3. 「依赖项是否需要深层比较」:注意依赖项是否是引用类型(如对象或数组)。如果依赖项是引用类型,它们的内容可能在地址不变的情况下发生变化。在这种情况下,你可能需要自行处理深层比较,以确保正确触发重新计算。

  4. 「避免不必要的内存占用」:虽然 useMemo 可以用于缓存引用类型,但要小心不要在不需要的情况下缓存大型对象或数组,以避免不必要的内存占用。在某些情况下,直接传递引用类型的变化可能更合适。

  5. 「记住 useMemo 返回的是值」useMemo 返回的是计算的值,而不是函数。如果需要缓存函数,应该使用 useCallback

  6. 「性能监控工具」:使用性能监控工具(如 React DevTools)来检查 useMemo 缓存的值是否按预期工作。这有助于排除性能问题和调试问题。

  7. 「组件层次结构考虑」useMemo 只在当前组件内有效。如果需要在多个组件之间共享缓存值,可能需要提升状态或使用上下文(Context)。


欢迎点赞、关注、转发~ alt

本文由 mdnice 多平台发布

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

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

相关文章

【LangChain系列 5】Prompt模版——特征库

原文地址:【LangChain系列 5】Prompt模版——特征库 本文速读: Feast Featureform 特征库(feature stores)是传统机器学习中的一个概念,本质上是数据,不同维度/属性的数据,而且可以保持同步更新,所以可以…

React中函数式组件与类组件有何不同?

Function Component 与 Class Component 有何不同 目录 Function Component 与 Class Component 有何不同 文章核心观点: 解释一下: 总结: 文章核心观点: Function components capture the rendered values.函数式组件捕获…

【PyQT5教程】-02-UI组件

1.按钮 QtWidgets模块提供了多种按钮类,让你可以轻松地创建各种类型的按钮 1.1 QPushButton(普通按钮) QPushButton是PyQt5中最常见的按钮类型之一,用于触发动作或执行操作。通过信号与槽机制,你可以将按钮的点击事…

性能测试 —— 生成html测试报告、参数化、jvm监控

1.生成HTML的测试报告 1.1配置 (1)找到jmeter 的安装目录,下的bin中的jmeter.properties(jmeter配置文件) (2) ctrl f ,搜索jmeter.save.saveservice.output_format,取消井号 并且 把等号后的xml改为csv,…

基于Intel优化的淡水养殖水质溯源方案

基于AI的淡水养殖水质溯源、优化系统方案 前言一、核心痛点及关键需求1.政策引导及产业升级2.紧跟时事及供给变化3.品牌打造,重拾消费者信赖4.特色生态新模式 二、方案设计1.水质溯源档案2.数字孪生系统3.基于intel AI 水质预测算法 三、实践案例1、方案简述2、数据…

聊聊低代码的全栈开发能力

一、前言 低代码的热度持续提升,最明显的举动就是资本真金白银的投资。 阿里推出“云钉一体”战略,为企业提供全生命周期的IT解决文案;腾讯将各个事业部的低代码平台进行整合,推出了OTeam平台。网易有数帆轻舟低代码平台&#xff…

CentOS7无法连接网络 右上角网络图标消失

在使用 linux 的过程中,有时会出现网络图标消失的问题,这时系统会没有网络。 有些 linux 的网络连接由 NetworkManager 管理, 问题应由它解决。 先执行一下 systemctl restart NetworkManager 看有没有效果。 原因一 :NetworkMan…

Kafka3.1部署和Topic主题数据生产与消费

文章目录 前言一、Kafka3.1X版本在Windows11主机部署二、Kafk生产Topic主题数据1.kafka生产数据2.JAVA kafka客户端消费数据 总结 前言 本章节主要讲述Kafka3.1X版本在Windows11主机下部署以及JAVA对Kafka应用: 一、Kafka3.1X版本在Windows11主机部署 1.安装JDK配…

Spring Boot 集成MQTT代码示例

文章目录 1. 简介使用场景 2. 搭建MQTT测试环境服务1. 先创建映射目录2. 创建两个文件2.1. mosquitto.conf 3. 启动 MQTT服务 Docker 容器3.1. 配置用户名和密码3.1.1. 创建密码文件3.1.2. 修改配置文件,追加密码文件 3.2. 重启mosquitto 容器服务 3. 编写测试程序3…

2023--9-8 高斯消元解线性方程组

题目链接&#xff1a;高斯消元解线性方程组 #include <iostream> #include <algorithm> #include <cmath>using namespace std;const int N 110; const double eps 1e-8;int n; double a[N][N];int gauss() {int c, r;for(c 0, r 0; c < n; c){// 找到…

(其他) 剑指 Offer 64. 求1+2+…+n ——【Leetcode每日一题】

❓ 剑指 Offer 64. 求12…n 难度&#xff1a;中等 求 12...n &#xff0c;要求不能使用乘除法、for、while、if、else、switch、case 等关键字及 条件判断语句&#xff08;A?B:C&#xff09;。 示例 1&#xff1a; 输入: n 3 输出: 6 示例 2&#xff1a; 输入: n 9 输出:…

LeetCode(力扣)491. 递增子序列Python

LeetCode491. 递增子序列 题目链接代码 题目链接 https://leetcode.cn/problems/non-decreasing-subsequences/ 代码 class Solution:def backtracking(self, nums, index, result, path):if len(path) > 1:result.append(path[:])uset set()for i in range(index, len…

小程序实现摄像头拍照 + 水印绘制

文章标题 01 功能说明02 使用方式 & 效果图2.1 基础用法2.2 拍照 底部定点水印 预览2.3 拍照 整体背景水印 预览 03 全部代码3.1 页面布局 html3.2 业务核心 js3.3 基础样式 css 01 功能说明 需求&#xff1a;小程序端需要调用前置摄像头进行拍照&#xff0c;并且将拍…

当面试官问你离职原因的时候怎么回答比较好?

所有的前提都是建立在有一定的物质基础&#xff0c;当你的一日三餐都成了问题&#xff0c;都需要家庭支持的时候我希望你可以找一份工作&#xff0c;靠自己的本事养活自己从来不丢人&#xff0c;我觉得死要面子活受罪才是真的让你看不起。 所有的建议都是建立在我们是普通打工人…

如何用Jmeter编写脚本压测?

随着商业业务不断扩张&#xff0c;调用adsearch服务频率越来越高&#xff0c;所以这次想做个压测&#xff0c;了解目前多少并发量可以到达adsearch服务的界值。 这次选用的jmeter压测工具&#xff0c;压测思路如图&#xff1a; 一、日志入参 日志选取的adsearch 的 getads部分…

电工-什么是电流

什么是电流&#xff1f;电流计算公式和单位换算及电流方向讲解 前面了解到电路的基本组成是包括&#xff1a;电能、负载、导线构成的&#xff0c;而这电路就是电流流通的路径&#xff0c;那么什么是电流呢&#xff1f;下面就讲讲电流形成的基本概念以及电流计算公式、单位和方…

2023-9-8 求组合数(二)

题目链接&#xff1a;求组合数 II #include <iostream> #include <algorithm>using namespace std;typedef long long LL; const int mod 1e9 7; const int N 100010;// 阶乘&#xff0c;阶乘的逆 int fact[N], infact[N];LL qmi(int a, int k, int p) {int res…

HTTPS 之fiddler抓包--jmeter请求

一、浅谈HTTPS 我们都知道HTTP并非是安全传输&#xff0c;在HTTPS基础上使用SSL协议进行加密构成的HTTPS协议是相对安全的。目前越来越多的企业选择使用HTTPS协议与用户进行通信&#xff0c;如百度、谷歌等。HTTPS在传输数据之前需要客户端&#xff08;浏览器&#xff09;与服…

selenium的Chrome116版驱动下载

这里写自定义目录标题 下载地址https://googlechromelabs.github.io/chrome-for-testing/#stable 选择chromedriver 对应的平台和版本 国内下载地址 https://download.csdn.net/download/dongtest/88314387

分享一个Python Django影片数据爬取与数据分析系统源码

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…