当前位置: 首页 > news >正文

useCallback 与 useMemo 的区别 作用

useCallback 缓存钩子函数,useMemo 缓存返回值(计算结果)

TS声明如下:type DependencyList = ReadonlyArray<any>;function useCallback<T extends (...args: any[]) => any>(callback: T, deps: DependencyList): T;function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T;

一些文章长篇大论解释,其实直接看 typescript 声明就知道作用了,泛型 T 在 useCallback 中是一个钩子函数,在 useMemo 中是一个返回值。

demo示例

一个简单计数器 demo 解释全部作用:点击按钮 count 加 1,同时显示这个数是奇数还是偶数

不用 hook 的代码

import React, { FC, useCallback, useMemo, useState } from 'react';const Index: FC = (props) => {const [count, setCount] = useState(0);const isEvenNumber = count % 2 === 0;const onClick = () => setCount(count + 1);return (<div><div>{count} is {isEvenNumber ? 'even':'odd'} number</div><button onClick={onClick}></button></div>);
};

使用 hook 后的代码

import React, { FC, useCallback, useMemo, useState } from 'react';const Index: FC = (props) => {const [count, setCount] = useState(0);const isEvenNumber = useMemo(() => {return count % 2 === 0;}, [count]);const onClick = useCallback(() => {setCount(count + 1);}, [count]);return (<div><div>{count} is {isEvenNumber ? 'even':'odd'} number</div><button onClick={onClick}></button></div>);
};

看起来没有什么区别,甚至使用 hook 后代码还变复杂了。这个 demo 比较简单,所有使用 hook 后的优化效果不明显,大部分代码即使使用第一种写法都没有太大区别,用户无感知,但系统逐步升级后为了占用更小的内存、更流畅的使用体验 hook 是必要的。

作用

如果不使用 hook,每次组件 re-render 的时候,都需要重新计算 isEvenNumber 的值,以及 new 一个 onClick 函数,即使每次计算结果没有改变,也要重复这个浪费内存的操作,hook 可以缓存相关结果,避免重复渲染时的无效计算。

useCallback 和 useMemo 的参数都是一个函数加一个依赖数组,依赖没有改变时直接返回内存中缓存的结果,无需重复计算。简单理解就是 useCallback 缓存事件处理函数,useMemo 缓存二次计算的结果,如上面的点击事件,以及通过 count 值判断奇数偶数的二次计算结果。

本质原因

React 的函数组件是非常好用的东西,相比 class 写法以及 Vue 的对象挂载写法简洁很多,代码测试复用成本低,容易入手,但也带来一些问题,无状态函数很理想,但现实有一些计算开销大、组件渲染频繁的场景是需要状态的,每次都计算一遍状态(callback 和 二次计算值)无疑很浪费内存,函数不像对象(React class 写法或者 Vue 组件写法)可以直接将状态挂载在自身,没有浪费内存的问题,要实现类似的效果只能找一个的内存挂载点挂载这些东东,所以有了 useCallback 和 useMemo 这些 hook。

useCallback和useMemo的区别

  • 相同点:
    1. useCallback 和 useMemo 参数相同,第一个参数是函数,第二个参数是依赖项的数组。
    2. useMemo、useCallback 都是使参数(函数)不会因为其他不相关的参数变化而重新渲染。
    3. 与 useEffect 类似,[] 内可以放入你改变数值就重新渲染参数(函数)的对象。如果 [] 为空就是只渲染一次,之后都不会渲染
  • 区别:
    • 主要区别是 React.useMemo 将调用 fn 函数并返回其结果,而 React.useCallback 将返回 fn 函数而不调用它。
http://www.lryc.cn/news/38243.html

相关文章:

  • Mybatis的学习
  • PyTorch深度学习实战 | 计算机视觉
  • 力扣(LeetCode)436. 寻找右区间(2023.03.10)
  • 已解决Servlet中Request请求参数中文乱码的问题
  • 【flask】URL和视图映射
  • Python实现性能测试(locust)
  • 【数论】试除法判断质数,分解质因数,筛质数
  • 【C++】红黑树
  • 【剧前爆米花--爪哇岛寻宝】进程的调度以及并发和并行,以及PCB中属性的详解。
  • 网络的瓶颈效应
  • 【C++进阶】四、红黑树(三)
  • Spring——AOP切入点表达式和AOP通知类型
  • Hadoop学习:Yarn
  • Spring Data JPA
  • java List报错Method threw ‘java.lang.UnsupportedOperationException‘ exception. 解决
  • 数据结构-用栈实现队列
  • 第十四章 从 Windows 客户端控制 IRIS
  • 数据结构---双链表
  • Windows 环境安装Scala详情
  • C++ Qt自建网页浏览器
  • Flink从入门到精通系列(四)
  • Nginx 配置实例-反向代理案例一
  • 为什么北欧的顶级程序员数量远超中国?
  • vuex getters的作用和使用(求平均年龄),以及辅助函数mapGetters
  • 20230311给Ubuntu18.04下的GTX1080M安装驱动
  • 2023腾讯面试真题:
  • 23种设计模式-建造者模式(Android应用场景介绍)
  • English Learning - L2 语音作业打卡 双元音 [ʊə] [eə] Day17 2023.3.9 周四
  • 【动态规划】多重背包问题,分组背包问题
  • JAVA面向对象特征之——封装