【React】memo()、useCallback()、useMemo()的区别及使用场景

介绍React中三个hooks方法memo useCallback useMemo的作用及使用场景示例

  • 一、React.memo():用来控制函数组件的重新渲染,将组件作为参数,函数的返回值是一个新的组件。
  • 二、React.useCallback():将回调函数及依赖项数组作为参数传入;
  • 三、React.useMemo():将“创建”函数和依赖项数组作为参数传入;
  • 四、结论

一、React.memo():用来控制函数组件的重新渲染,将组件作为参数,函数的返回值是一个新的组件。

import { useState} from "react";
const Child = () => {console.log("我是子组件", "渲染了");return <div>我是子组件</div>;
};
export const Parent = () => {const [count, setCount] = useState(0);const increment = () => setCount(count + 1);return (<div><button onClick={increment}>点击次数:{count}</button><Child /></div>);
};

每点击一次,子组件的useState、props和context都没有改变,但是每点击一次子组件都会重新渲染

解决办法:将memo函数包裹子组件

import { memo } from "react";
const Child = memo(() => {console.log("我是子组件", "渲染了");return <div>我是子组件</div>;
});

二、React.useCallback():将回调函数及依赖项数组作为参数传入;

  • 它的主要作用是缓存一个回调函数,以确保在组件重新渲染时不会创建新的回调函数,从而减少不必要的性能开销。useCallback 通常与 React.memo 或 shouldComponentUpdate 一起使用,以避免不必要的组件重新渲染。
import { useState,memo } from "react";
const Child =  memo((props: { name: string; onClick: Function }) => {const { name, onClick } = props;console.log("我是子组件", "渲染了");return (<><div>我是子组件={name}</div><button onClick={() => onClick("修改父组件传过来的参数")}>改变 name 值</button></>);
});
export const Parent = () => {const [count, setCount] = useState(0);const [name, setName] = useState("向子组件传递参数");const increment = () => setCount(count + 1);const onClick = (name: string) => {setName(name);};return (<div><button onClick={increment}>点击次数:{count}</button><Child name={name} onClick={onClick} /></div>);
};

每点击一次父组件的按钮,子组件都会重新渲染;

原因

  • 点击父组件按钮,父组件中 count 改变,进而导致父组件重新渲染;
  • 父组件重新渲染时,会重新创建 onClick 函数,即传给子组件的 onClick 属性发生了变化,导致子组件渲染;
  • 如果传给子组件的props只有[基本数据类型](https://blog.csdn.net/m0_61049675/article/details/135815841),子组件将不会重新渲染。

解决办法:修改父组件的 onClick 方法,用 useCallback 钩子函数包裹一层。
注意: 如果直接使用useState解构的setName传给子组件, 子组件将不会重复渲染,即使用<Child name={name} setName={setName} />

  const onClick = useCallback((name: string) => {setName(name);}, []);

三、React.useMemo():将“创建”函数和依赖项数组作为参数传入;

import { useState,memo } from "react";
const Child =  memo((props: { userInfo: { name: string; age: number } }) => {const { userInfo} = props;console.log("我是子组件", "渲染了");return (<><div>我是子组件={userInfo}</div><button>改变 name 值</button></>);
});
export const Parent = () => {const [count, setCount] = useState(0);const userInfo = ({ name: "小明", age: 18 });const increment = () => setCount(count + 1);return (<div><button onClick={increment}>点击次数:{count}</button><Child userInfo={userInfo}/></div>);
};

每点击一次父组件的按钮,子组件都会重新渲染;

原因

  • 点击父组件按钮,父组件重新渲染;
  • 父组件重新渲染时,会重新生成一个新对象userInfo ,即传给子组件的 userInfo 属性发生了变化,导致子组件渲染;
    解决办法:使用 useMemo 将对象属性包一层。
    注意: 如果直接使用useState解构的userInfo, 子组件将不会重复渲染,即使用const [userInfo, setUserInfo] = useState({ name: "小明", age: 18 });
const userInfo = useMemo(() => ({ name: "小明", age: 18 }), []);

四、结论

  • useMemo返回的是一个变量的值,useCallback返回的是一个函数。
  • useMemo就是作为一个值来使用的,而useCallback则是被绑定的onClick,作为要执行的函数。
  • useCallback和useMemo主要用来做数据缓存,它们的更新依赖于第二个参数是否发生了变化。因此当我们的render重复渲染时,只要我们的useMemo和useCallback的第二个参数值没有发生变化,useMemo和useCallback则不会执行第一个参数里的函数。
  • 当父组件重新发生render的时候,子组件接受父组件的自定义方法,如果我不希望子组件发生变化,那么就需要用useCallback包裹父组件的自定义函数;

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

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

相关文章

【Python】Unindent does not match any outer indentation level

这个问题一般是代码缩进问题导致的&#xff0c;规范代码缩进格式即可&#xff0c;如图&#xff1a; 这个问题是因为报异常的那行代码下的方法缩进问题导致&#xff0c;def calendar_f(): 方法名前面多了一个空格。 删除空格即可解决此问题。

【python】python爱心代码【附源码】

一、实现效果&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 二、完整代码&#xff1a; import math import random import threading import time from math import sin, cos, pi, log from tkinter import * import re# 烟花相关设置 Fireworks [] m…

Fink CDC数据同步(五)Kafka数据同步Hive

6、Kafka同步到Hive 6.1 建映射表 通过flink sql client 建Kafka topic的映射表 CREATE TABLE kafka_user_topic(id int,name string,birth string,gender string ) WITH (connector kafka,topic flink-cdc-user,properties.bootstrap.servers 192.168.0.4:6668…

iview 页面中判断溢出才使用Tooltip组件

使用方法 <TextTooltip :content"contentValue"></TextTooltip> 给Tooltip再包装一下 <template><Tooltip transfer :content"content" :theme"theme" :disabled"!showTooltip" :max-width"300" :p…

滴滴面经相关知识整理(基于newbing)

Vue2和Vue3有许多不同之处&#xff0c;以下是一些主要的区别&#xff1a; 数据劫持方式&#xff1a;Vue2主要是通过Object.defineProperty劫持数据&#xff0c;对于新增的对象属性&#xff0c;使用数组修改元素&#xff0c;视图无法更新1。 性能和体积&#xff1a;Vue3的运行速…

Spring auto-configuration的使用

简介 在构建Maven项目时&#xff0c;使用Spring Boot自动配置可以使项目更易于集成和使用。本文将向您展示如何创建一个Maven项目&#xff0c;并使用Spring Boot自动配置使其能够被其他组件方便地依赖。 步骤 1. 添加Spring Boot Starter依赖 确保您的Maven项目具有必要的S…

跟着cherno手搓游戏引擎【20】混合(blend)

抽象&#xff1a; Renderer.h: #pragma once #include"RenderCommand.h" #include "OrthographicCamera.h" #include"Shader.h" namespace YOTO {class Renderer {public:static void Init();static void BeginScene(OrthographicCamera& …

天拓四方:边缘计算网关功能、特点与应用举例

传统的数据处理方式面临网络延迟、带宽限制和安全风险等问题。为了解决这些问题&#xff0c;边缘计算技术应运而生&#xff0c;而边缘计算网关作为其核心组件&#xff0c;正发挥着越来越重要的作用。边缘计算网关位于数据源和云数据中心之间。它具备数据采集、协议转换、数据处…

Oracle 执行计划(Explain Plan)

执行计划&#xff1a;一条查询语句在 ORACLE 中的执行过程或访问路径的描述。即就是对一个查询任务&#xff0c;做出一份怎样去完成任务的详细方案。 如果要分析某条 SQL 的性能问题&#xff0c;通常我们要先看 SQL 的执行计划&#xff0c;看看 SQL 的每一步执行是否存在问题。…

视觉SLAM十四讲学习笔记(一)初识SLAM

目录 前言 一、传感器 1 传感器分类 2 相机 二、经典视觉 SLAM 框架 1 视觉里程计 2 后端优化 3 回环检测 4 建图 5 SLAM系统 三、SLAM 问题的数学表述 四、Ubuntu20.04配置SLAM十四讲 前言 SLAM: Simultaneous Localization and Mapping 同时定位与地图构建&#…

交友系统---让陌生人变成熟悉人的过程。APP小程序H5三端源码交付,支持二开。

随着社交网络的发展和普及&#xff0c;人们之间的社交模式正在发生着深刻的变革。传统的线下交友方式已经逐渐被线上交友取而代之。而同城交友正是这一趋势的产物&#xff0c;它利用移动互联网的便利性&#xff0c;将同城内的人们连接在一起&#xff0c;打破了时空的限制&#…

机器视觉系统设计:视觉系统中的成像基准

开发视觉系统的一个重要活动是验证其部署是否符合工程规范。一个成功的视觉应用程序的两个特点是它无需工程师干涉情况下正常工作了多长时间&#xff0c;以及它的维护和复制部署是多么简易。实现所有如上所述目标的一个关键步骤是确定视觉系统的基准。 在这里使用的上下文中&a…

移动云ONAIR媒体云全解读!媒体内容数字化融合一站式解决方案

当下&#xff0c;传统媒体面临着诸多挑战&#xff0c;如何利用信息技术提升内容的质量、形式和分发效率&#xff0c;成为媒体行业的迫切需求。移动云作为数字中国建设的“主力军”&#xff0c; 立足于新兴媒体与云计算市场的变化与需求&#xff0c;推出了ONAIR 媒体云解决方案&…

HTTP/2

HTTP/2核心 二进制帧 HTTP 2.0中所有加强性能的核心带你在于此–二进制传输 之前的HTTP/1的版本中&#xff0c;传输数据方式–文本传输 在 HTTP 2.0 中&#xff0c;有两个非常重要的概念&#xff0c;分别是帧&#xff08;frame&#xff09;和流&#xff08;stream&#xff0…

vue2学习笔记(2/2)

vue2学习笔记&#xff08;1/2&#xff09; vue2学习笔记&#xff08;2/2&#xff09; 文章目录 1. 初始化脚手架2. 分析脚手架&render函数文件结构图示及说明main.jsindex.htmlApp.vueSchool.vueStudent.vue 关于不同版本的Vue修改默认配置vue.config.js配置文件 3. ref属…

点灯科技esp32 idfv5.1组件库

最近研究了一下点灯科技的app&#xff0c;看到官方提供的esp32 idf组件库支持v4.3/v4.4,所以就将其移植一下&#xff0c;让其支持v5.1版本&#xff0c;下载地址如下&#xff1a; https://github.com/guxiangguo/blinker-esp-idf_v5.1.git https://gitee.com/gu-xiangguo/blin…

08. 【Linux教程】CentOS 目录介绍

CentOS 目录介绍 前面小节介绍了如何安装并登录连接 CentOS 系统&#xff0c;本小节围绕 CentOS 系统的目录&#xff0c;介绍其各个目录的作用&#xff0c;方便读者以后在工作中很好地将项目和软件归类存储&#xff0c;熟悉 CentOS 系统各个目录的功能介绍&#xff0c;有助于加…

035 Arrays类

示例 int[] nums new int[10]; // fill Arrays.fill(nums, 666); System.out.println(Arrays.toString(nums)); // sort nums new int[]{1, 3, 5, 7, 9, 2, 4, 6, 8}; Arrays.sort(nums); System.out.println(Arrays.toString(nums)); // equals int[] nums2 new int[]{1,…

【数据分享】1929-2023年全球站点的逐日平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;说到常用的降水数据&#xff0c;最详细的降水数据是具体到气象监测站点的降水数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全…

【Spring】代理模式

文章目录 代理模式对代理模式的理解静态代理动态代理JDK动态代理原理源码优化 CGLIB动态代理使用原理 JDK与CGLIB的对比 面试题JDK动态代理和CGLIB有什么区别&#xff1f;既然有没有接口都可以用CGLIB&#xff0c;为什么Spring还要使用JDK动态代理&#xff1f; 代理模式 对代理…