React 第十七节 useMemo用法详解

news/2024/12/21 14:13:52/

概述

useMemo 是React 中的一个HOOK,用于根据依赖在每次渲染时候缓存计算结果
大白话就是,只有依赖项发生变化时候,才会重新渲染为新计算的值,否则就还是取原来的值,有点类似 vue 中的 computed 计算属性,注意与 useEffect 区分;

写法

javascript">const value = useMemo(fnc, [a,b])

第一个参数fnc 是一个函数,用于根据 依赖项 a、b变化时候触发计算得出新值,必须是一个没有任何参数的纯函数,可以返回任意类型;若 a、b没有变化,则React 返回与上次相同的值;若 a、b 发生改变,则会返回新的值;
第二个参数[a、b] 是一个数组,函数 fnc中计算所依赖的值,这个数组中若不传入具体变量,而是传入 空数组[],那么会在组件每次更新时候重新渲染;

这种缓存值的方式叫做 记忆化 (memoization), 这也是这个Hook 称为 useMemo 的由来

使用场景

1、当我们在 useMemo 中的代码运行很慢,通过使用 useMemo 运行效率得到显著提升;
2、将计算结果作为 props 传递给包裹在 memo 中的组件。当计算结果没有改变时,你会想跳过重新渲染。记忆化让组件仅在依赖项不同时才重新渲染。
3、你传递的值稍后用作某些 Hook 的依赖项。例如,也许另一个 useMemo 计算值依赖它,或者 useEffect 依赖这个值。

例如:
将计算结果作为 props 传给子组件

javascript">// 父组件
import React, {useMemo, useState} from 'react'
import ChildA from './childA'
export default function MyMemo() {const [firstName, setFirstName] = useState('Andy')const [lastName, setLastName] = useState('Li')const [count, setCount] = useState(0)const fullName = useMemo(() => {console.log('==useMemo==')return firstName +'' + lastName}, [firstName, lastName]) // 第二个参数是数组,表示fullName 依赖 firstName 和 lastName 的值,只有 firstName 和 lastName 值发生变化,fullName 才重新计算const handleChangeName = (e, type) => {console.log('==handleChangeName==', e)// [`set${type}`](e.target.value)// if (type === 'FirstName') {//     setFirstName(e.target.value)// } else {//     setLastName(e.target.value)// }}const handleChangeFirstName = () => {console.log('==更新第一个名称=')setCount(count+1)setFirstName(11)}return (<div><input type="text"  value={firstName} onChange={(e) => handleChangeName(e, 'FirstName')} /><p>点击了{count}</p><button onClick={handleChangeFirstName}>firstName</button><br/><input type="text" value={lastName} onChange={(e) => handleChangeName(e, 'LastName')} /><hr /><ChildA fullName={fullName}></ChildA></div>)
}
javascript">// 子组件
import React, {memo, useState} from 'react'
const ChildA = memo(({fullName}) =>{console.log('=render=ChildA==fullName----', fullName)return (<div><p>全称:{fullName}</p></div>)
})
export default ChildA

在这里插入图片描述
通过 log日志,我们可以发现,共计点击了 firstName 按钮 18次;只有在初始化第一次点击时候才会渲染 子组件;
因为第一次点击将 firstName 更新为 11;之后的点击传入相同的值 11,导致 useMemo 返回的 fullName 是相同的,故不再进行渲染

而当我们使用 useEffect 时候,会每次都更新子组件

注意:

1、useMemo 只能作为组件代码性能优化使用,如果在不使用 useMemo时,代码无法正常运行,那么我们需要先排查问题,之后再使用 useMemo
2、避免不必要的更新 state 的 Effect;React 中很多的性能是由于其自身的更新链导致的,所以我们要避免重复的更新同一个组件
3、尽可能的减少依赖项,避免过多的依赖导致代码难以理解,难以追踪问题;我们可以将依赖项 设置成 state;
4、我们应该减少状态的提升,多使用state,而不是滥用useMemo来处理性能;


http://www.ppmy.cn/news/1556946.html

相关文章

CH340系列芯片驱动电路·CH340系列芯片驱动!!!

目录 CH340基础知识 CH340常见类型 CH340引脚功能讲解 CH340驱动电路 CH340系列芯片数据手册 编写不易&#xff0c;仅供学习&#xff0c;请勿搬运&#xff0c;感谢理解 常见元器件驱动电路文章专栏连接 LM7805系列降压芯片驱动电路降压芯片驱动电路详解-CSDN博客 ME62…

基础库正则表达式

我们已经可以用requests 库来获取网页的源代码&#xff0c;得到 HTML 代码。但我们真正想要的数据是包含在 HTML代码之中的&#xff0c;要怎样才能从 HTML,代码中获取想要的信息呢?正则表达式就是其中一个有效的方法。 本篇博客我们将了解一下正则表达式的相关用法。正则表达…

IDEA搭建SpringBoot,MyBatis,Mysql工程项目

目录 一、前言 二、项目结构 三、初始化项目 四、SpringBoot项目集成Mybatis编写接口 五、代码仓库 一、前言 构建一个基于Spring Boot框架的现代化Web应用程序&#xff0c;以满足[公司/组织名称]对于[业务需求描述]的需求。通过利用Spring Boot简化企业级应用开发的优势&…

STM32 水质水位检测项目(硬件架构)及(软件架构)

硬件选型 水位测量模块 TDS采集模块 外置ADC模块&#xff08;ADS1115&#xff09; 水位测量模块使用方法 水位测量原理 压力传感器&#xff1a;水越深压力越大 P ρgh Fps Fρgh*s P大气压 水位测量传感器本质上是一个压力测量传感器。压力的值和传感器产生的电压值是线…

高并发-缓存预热

缓存预热的必要性 缓存预热是为了在系统面临高并发请求时&#xff0c;确保热点数据已经被加载到缓存中&#xff0c;从而提高系统响应速度和稳定性。通过缓存预热&#xff0c;可以避免因数据未命中而导致的数据库压力激增。 典型应用场景 电商系统&#xff1a;在秒杀活动期间&…

git bash中文显示问题

个人博客地址&#xff1a;git bash中文显示问题 | 一张假钞的真实世界。 默认情况下git bash中文以ASCII编码&#xff0c;不方便查看&#xff0c;如下&#xff1a; $ git status 位于分支 master尚无提交要提交的变更&#xff1a;&#xff08;使用 "git rm --cached <…

GTID详解

概念和组成 1&#xff0c;全局事务表示&#xff1a;global transaction identifiers 2, GTID和事务一一对应&#xff0c;并且全局唯一 3&#xff0c;一个GTID在一个服务器上只执行一次 4&#xff0c;mysql 5.6.5开始支持 组成 GTID server_uuid:transaction_id 如&#xf…

vimdc

set nocompatible filetype on set rtp~/.vim/bundle/Vundle.vim call vundle#begin() " 这里根据自己需要的插件来设置&#xff0c;以下是我的配置 " " " YouCompleteMe:语句补全插件 set runtimepath~/.vim/bundle/YouCompleteMe autocmd InsertLe…