React Hook的用法: memo + useCallback (四)

2023-11-01 04:10

本文主要是介绍React Hook的用法: memo + useCallback (四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

React Hook的用法

React.memo

作用

React.memo的作用主要是用于缓存组件,使得组件可以按照业务的需求决定是否来更新的效果,比如业务场景中常见的一个场景,在页面的底部有一个版权说明,一般这是各个模块页面所公用的一个组件,但这个组件基本就是一个静态的文案描述,如果父组件数据变化更新的时候这个抽象出来的版权组件也无需更新,这样可以达到减少页面性能开销的目的。

在线示例

下面设计了一组三个不同效果的Demo做对比,父组件中有两个变量 age 和account传递给子组件,并且在父组件中可以更新这两个值。比较达到的效果如下表所列:

  1. Demo1 正常使用,父组件更新age 和account->父组件更新->子组件更新
  2. Demo2 使用 React.memo 来缓存子组件,父组件更新age 和 account->子组件不会更新
  3. Demo3 使用React.memo的第二个参数来达到选择行的更新,age变化时候子组件更新,account更新时不更新

展示效果如下所示:
在这里插入图片描述
在线Demo

在例子中的没个子组件中都打印出了一些信息,每当子组件重复渲染的时候都会打印出日志。

关键代码

import { useState, memo } from "react";

从React 中结构赋值的方式引入memo,当然也可以直接使用React.memo的写法

const MemoChild = memo(() => {console.log("子组件函数MemoChild...");return (<div className="child-container">这是子组件,内容固定,父组件更新的时候,我可以不用更新</div>);
});

可以看到memo是一个高阶组件,接受一个业务组件即可达到demo2的效果。一般如果子组件是一个纯展示的傻瓜组件,这么写就可以,如果子组件也是有逻辑需要根据父组件的变化来 ”选择性“的更新的时候,这个时候就需要使用第二个参数了。关键代码如下:

const MemoChild = memo(() => {console.log("子组件函数MemoChild...");return (<div className="child-container">这是子组件,内容固定,父组件更新的时候,我可以不用更新</div>);},(pre, next) => {console.log(pre, next);return pre.age === next.age;}
);

可以看到,memo的第二个参数也是一个函数,该函数接受两个参数,分别是之前的属性状态值和下一个属性的状态值,那就可以在这里做一些业务的判断来决定子组件是否需要更新,返回true标识前后两个状态值一样,则不更新,返回false则表示前后两个状态的值不一样则会更新,从而达到 子组件”选择性“的去更新的效果类似Demo3
如果不传的第二个参数的话,默认前后两个状态会做浅比较,根据这个比较的结果来决定子组件是否更新。

useCallback

作用

一言以蔽之其作用就是来缓存某个函数,就好像 useMemo是缓存某个变量一样,useCallback 是用来缓存某个函数。避免一个函数的更新导致某个组件随着一起更新。
可能这样比较晦涩,直接看一个Demo,就可以理解了。

在线示例

例子的目的是希望父组件中能同步展示子组件输入框中输入的值。
那一般我们会这么写,父组件会传递给子组件一个onChange函数,自子组件会在Input输入框中监听onChang事件,并在每次输入框发生变化的时候去触发父组件传递过来的onChange事件。这样做没有问题,可以达到我们预期的功能,但你会发现每次输入框变化的时候,子组件都会重新更新一遍,但其实在这个场景中,子组件是不需要重新渲染的。只希望父组件能监听到子组件的onChange事件并获取输入的值展示即可。效果如下:
在这里插入图片描述
可以看到效果是达到预期的,但是随着输入框的变化,子组件一直在重复渲染。
原因如下:
用户输入->触发子组件onChange事件->触发父组件handleChange函数->父组件修改inputTxt的状态值->状态值改变导致父组件重新渲染->handleChange函数体会重新注册一遍->传递给子组件的onChange也会一起变(这个时候的onChange事件和之前的并不一样)->子组件重复渲染
因为上面的这个逻辑所以才导致了这个现象,所以就出现了useCallback的Hook,来规避这种重复渲染浪费性能的现象。先看使用之后达到的效果如何:

在这里插入图片描述
可以看到实现的效果和上面是一样的,但这里使用了useCallback之后就很好的规避了子组件重复渲染的问题。

在线Demo

关键代码

const handleChange = useCallback(e => {setInputTxt(e.target.value);}, []);

在父组件定义 handleChange 的时候使用 useCallback包裹一下,同样的这里的第二个参数也是依赖项。可以看到用法和 uesMemo, useEffect几乎一样。只是作用的对象有所不一样而已。
当然子组件也还是需要使用React.memo包裹一下,否则不work

const Child = memo(props => {console.log("子组件渲染Demo2...");return (<div className="child-container mt10"><Input placeholder="input" onChange={props.onChange} /></div>);
});

总结

这里将 memo, useMemo, useCallback 三个Hook放在一起做个对比归纳如下:

  1. React.memo 缓存组件,使得组件可以 ”有选择“的更新
  2. useMemo 缓存某个变量,第二个参数是依赖项。使得函数组件变量变化时候,组件可以”有选择“的去执行某些业务
  3. useCallBack 缓存某个方法,特别是子组件调父组件的场景,避免子组件重复渲染,useCallBack其实是 useMemo的一种简单用法,也可以直接使用useMemo 来缓存方法,不过一般使用useCallBack的比较多

这篇关于React Hook的用法: memo + useCallback (四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/320380

相关文章

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

解读GC日志中的各项指标用法

《解读GC日志中的各项指标用法》:本文主要介绍GC日志中的各项指标用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基础 GC 日志格式(以 G1 为例)1. Minor GC 日志2. Full GC 日志二、关键指标解析1. GC 类型与触发原因2. 堆

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的