React -- memo允许你的组件在 props 没有改变的情况下跳过重新渲染。

memo(Component, arePropsEqual?) 

使用 memo 将组件包装起来,以获得该组件的一个 记忆化 版本。通常情况下,只要该组件的 props 没有改变,这个记忆化版本就不会在其父组件重新渲染时重新渲染。但 React 仍可能会重新渲染它:记忆化是一种性能优化,而非保证。

import { memo } from 'react';const SomeComponent = memo(function SomeComponent(props) {// ...
});

参数

  • Component:要进行记忆化的组件。memo 不会修改该组件,而是返回一个新的、记忆化的组件。它接受任何有效的 React 组件,包括函数组件和 forwardRef 组件。

  • 可选参数 arePropsEqual:一个函数,接受两个参数:组件的前一个 props 和新的 props。如果旧的和新的 props 相等,即组件使用新的 props 渲染的输出和表现与旧的 props 完全相同,则它应该返回 true。否则返回 false。通常情况下,你不需要指定此函数。默认情况下,React 将使用 Object.is 比较每个 prop。

返回值
memo 返回一个新的 React 组件。它的行为与提供给 memo 的组件相同,只是当它的父组件重新渲染时 React 不会总是重新渲染它,除非它的 props 发生了变化。

用法

当 props 没有改变时跳过重新渲染
React 通常在其父组件重新渲染时重新渲染一个组件。你可以使用 memo 创建一个组件,当它的父组件重新渲染时,只要它的新 props 与旧 props 相同时,React 就不会重新渲染它。这样的组件被称为 记忆化的(memoized)组件。

要记忆化一个组件,请将它包装在 memo 中,使用它返回的值替换原来的组件:

const Greeting = memo(function Greeting({ name }) {return <h1>Hello, {name}!</h1>;
});export default Greeting;

React 组件应该始终具有 纯粹的渲染逻辑。这意味着如果其 props、state 和 context 没有改变,则必须返回相同的输出。通过使用 memo,你告诉 React 你的组件符合此要求,因此只要其 props 没有改变,React 就不需要重新渲染。即使使用 memo,如果它自己的 state 或正在使用的 context 发生更改,组件也会重新渲染。

在此示例中,请注意 Greeting 组件在 name 更改时重新渲染(因为那是它的 props 之一),但是在 address 更改时不会重新渲染(因为它不作为 props 传递给 Greeting):

import { memo, useState } from 'react';export default function MyApp() {const [name, setName] = useState('');const [address, setAddress] = useState('');return (<><label>Name{': '}<input value={name} onChange={e => setName(e.target.value)} /></label><label>Address{': '}<input value={address} onChange={e => setAddress(e.target.value)} /></label><Greeting name={name} /></>);
}const Greeting = memo(function Greeting({ name }) {console.log("Greeting was rendered at", new Date().toLocaleTimeString());return <h3>Hello{name && ', '}{name}!</h3>;
});

更改Address,Geeting没有重渲染。
在这里插入图片描述
更改name,Greeting重新渲染了
在这里插入图片描述
在这里插入图片描述

在每个地方都应该添加 memo 吗?

如果你的应用像此站点一样,大多数交互是粗略的(例如直接替换页面或整个部分),那么通常不需要记忆化。另一方面,如果你的应用更像是绘图编辑器,大多数交互是细粒度的(例如移动图形),那么你可能会发现记忆化非常有用。

只有当你的组件经常使用完全相同的 props 重新渲染时,并且其重新渲染逻辑是非常昂贵的,使用 memo 优化才有价值。如果你的组件重新渲染时没有明显的延迟,那么 memo 就不必要了。请记住,如果传递给组件的 props 始终不同,例如在渲染期间传递对象或普通函数,则 memo 是完全无用的。这就是为什么你通常需要在 memo 中同时使用 useMemo useCallback

在其他情况下将组件包装在 memo 中是没有任何好处的。这种做法也没有什么明显的危害,因此一些团队会选择不考虑个别情况,并尽可能使用 memo。这种方法的缺点是代码变得不易读。此外,并不是所有的记忆化都是有效的:一个“总是新的”值足以破坏整个组件的记忆化。

实践中,你可以通过遵循一些原则来使许多 memoization 变得不必要:

当一个组件在视觉上包裹其他组件时,让它 接受 JSX 作为子组件。这样,当包装组件更新其自身状态时,React 知道其子组件不需要重新渲染。
优先使用局部状态,并且不要将 状态提升 到不必要的层级。例如,不要将短暂状态(如表单数据和项元素是否 hover 状态)保留在树的顶部或全局状态库中。
保持你的 渲染逻辑纯粹。如果重新渲染组件会导致问题或产生一些明显的视觉瑕疵,则这是你组件中的 bug!修复 bug 而不是添加 memoization。
避免 不必要的 Effect 来更新状态。React 应用中的大多数性能问题都是由于 Effect 引起的更新链,这些 Effect 会使你的组件一次又一次地重新渲染。
尝试 从你的 Effect 中删除不必要的依赖项。例如,与其使用 memoization,不如将某些对象或函数移动到 Effect 内部或组件外部,这通常更简单。
如果特定交互仍然感觉不流畅,请 使用 React 开发者工具 profiler 来查看哪些组件最需要 memoization,并在需要时添加 memoization。这些原则使你的组件更易于调试和理解,因此建议在任何情况下都遵循它们。从长远来看,我们正在研究 自动进行细粒度 memoization,以解决这个问题。

当组件的某个 prop 是对象、数组或函数时,我的组件会重新渲染。

React 通过浅比较来比较旧的和新的 prop:也就是说,它会考虑每个新的 prop 是否与旧 prop 引用相等。如果每次父组件重新渲染时创建一个新的对象或数组,即使它们每个元素都相同,React 仍会认为它已更改。同样地,如果在渲染父组件时创建一个新的函数,即使该函数具有相同的定义,React 也会认为它已更改。为了避免这种情况,可以简化 props 或在父组件中记忆化(memoize)props。
官网讲解: memo

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

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

相关文章

java 大型企业MES生产管理系统源码:MES系统与柔性化产线控制系统的关系、作用

MES定义为“位于上层的计划管理系统与底层的工业控制之间的面向车间层的管理信息系统”,它为操作人员/管理人员提供计划的执行、跟踪以及所有资源(人、设备、物料、客户需求等)的当前状态。 MES系统与柔性化产线控制系统的关系 MES&#xff08;制造执行系统&#xff09;是一种…

离散数学---树

目录 1.基本概念及其相关运用 2.生成树 3.有向树 4.最优树 5.前缀码 1.基本概念及其相关运用 &#xff08;1&#xff09;无向树&#xff1a;连通而且没有回路的无向图就是无向树&#xff1b; 森林就是有多个连通分支&#xff0c;每个连通分支都是树的无连通的无向图&…

pytorch构建模型训练数据集

pytorch构建模型训练数据集 pytorch构建模型训练数据集1.AlexNet:1.1.导入必要的库&#xff1a;1.2.数据预处理和增强&#xff1a;1.3.加载数据集&#xff1a;1.4.划分测试集和训练集&#xff1a;1.5.创建数据加载器&#xff1a;1.6.加载AlexNet模型&#xff1a;1.7.修改模型以…

训练营第三十一天 | 494.目标和474.一和零动态规划:完全背包理论基础518.零钱兑换II

494.目标和 力扣题目链接(opens new window) 难度&#xff1a;中等 给定一个非负整数数组&#xff0c;a1, a2, ..., an, 和一个目标数&#xff0c;S。现在你有两个符号 和 -。对于数组中的任意一个整数&#xff0c;你都可以从 或 -中选择一个符号添加在前面。 返回可以使…

mysql当前状态分析(show status)

文章目录 查看当前线程数据查询连接情况查询缓存相关查询锁相关查询增删改查执行次数查询DDL创建相关 SHOW STATUS 是一个在 MySQL 中用来查看服务器运行状态的命令。它可以帮助你了解服务器的当前性能&#xff0c;包括连接数、表锁定、缓冲区使用情况等信息。 查看当前线程数据…

电机专用32位MCU PY32MD310,Arm® Cortex-M0+内核

PY32MD310是一颗专为电机控制设计的MCU&#xff0c;非常适合用做三相/单相 BLDC/PMSM 的主控芯片。芯片采用了高性能的 32 位 ARM Cortex-M0 内核&#xff0c;QFN32封装。内置最大 64 Kbytes flash 和 8 Kbytes SRAM 存储器&#xff0c;最高48 MHz工作频率&#xff0c;多达 16 …

Vue2工程化

本节目标 工程化开发项目运行流程组件化组件注册自定义创建项目 工程化开发 基于构建工具的环境开发Vue Webpack的缺点 webpack的配置并不简单基础的配置雷同各公司缺乏统一标准 Vue CLI Vue CLI是Vue官方提供的一个全局命令工具帮助我们快速创建标准化的开发环境( 集成了w…

图解通用网络IO底层原理、Socket、epoll、用户态内核态······

LInux 操作系统中断 什么是系统中断 这个没啥可说的&#xff0c;大家都知道&#xff1b; CPU 在执行任务途中接收到中断请求&#xff0c;需要保存现场后去处理中断请求&#xff01;保存现场称为中断处理程序&#xff01;处理中断请求也就是唤醒对应的任务进程来持有CPU进行需要…

YOLOv10开源,高效轻量实时端到端目标检测新标准,速度提升46%

前言 实时目标检测在自动驾驶、机器人导航、物体追踪等领域应用广泛&#xff0c;近年来&#xff0c;YOLO 系列模型凭借其高效的性能和实时性&#xff0c;成为了该领域的主流方法。但传统的 YOLO 模型通常采用非极大值抑制 (NMS) 进行后处理&#xff0c;这会增加推理延迟&#…

gulimall-search P125 springboot整合elasticsearch版本冲突

一、问题 spring-boot.version 2.2.4.RELEASE,在gulimall-search pom.xml中添加elasticsearch.version 7.4.2后&#xff0c;发现出现如下问题&#xff1a;elasticsearch版本是springboot引入的6.8.6&#xff0c;没有变为7.4.2。 二、原因 在gulimall-search 的pom文件中&#…

【数据结构】平衡二叉树左旋右旋与红黑树

平衡二叉树左旋右旋与红黑树 平衡二叉树 定义 平衡二叉树是二叉搜索树的一种特殊形式。二叉搜索树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;是一种具有以下性质的二叉树&#xff1a; 对于树中的每个节点&#xff0c;其左子树中的所有节点都小于该节点的值…

Python - 深度学习系列38 重塑实体识别5-预测并行化改造

说明 在重塑实体识别4中梳理了数据流&#xff0c;然后我发现pipeline的串行效率太低了&#xff0c;所以做了并行化改造。里面还是有不少坑的&#xff0c;记录一下。 内容 1 pipeline 官方的pipeline看起来的确是比较好用的&#xff0c;主要是实现了比较好的数据预处理。因为…

党史馆3d网上展馆

在数字化浪潮的推动下&#xff0c;华锐视点运用实时互动三维引擎技术&#xff0c;为用户带来前所未有的场景搭建体验。那就是领先于同行业的线上三维云展编辑平台搭建编辑器&#xff0c;具有零基础、低门槛、低成本等特点&#xff0c;让您轻松在数字化世界中搭建真实世界的仿真…

【SpringBoot】SpringBoot整合RabbitMQ消息中间件,实现延迟队列和死信队列

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;死信队列 RabbitMQ的工作模式 死信队列的工作模式 二、&#x1f349;RabbitMQ相关的安装 三、&#x1f34e;SpringBoot引入RabbitMQ 1.引入依赖 2.创建队列和交换器 2.1 变量声明 2.2 创建…

Python实现半双工的实时通信SSE(Server-Sent Events)

Python实现半双工的实时通信SSE&#xff08;Server-Sent Events&#xff09; 1 简介 实现实时通信一般有WebSocket、Socket.IO和SSE&#xff08;Server-Sent Events&#xff09;三种方法。WebSocket和Socket.IO是全双工的实时双向通信技术&#xff0c;适合用于聊天和会话等&a…

SwiftUI中Mask修饰符的理解与使用

Mask是一种用于控制图形元素可见性的图形技术&#xff0c;使用给定视图的alpha通道掩码该视图。在SwiftUI中&#xff0c;它类似于创建一个只显示视图的特定部分的模板。 Mask修饰符的定义&#xff1a; func mask<Mask>(alignment: Alignment .center,ViewBuilder _ ma…

AI论文速读 | 2024[KDD]GinAR—变量缺失端到端多元时序预测

题目&#xff1a;GinAR: An End-To-End Multivariate Time Series Forecasting Model Suitable for Variable Missing 作者&#xff1a;Chengqing Yu&#xff08;余澄庆&#xff09;, Fei Wang&#xff08;王飞&#xff09;, Zezhi Shao&#xff08;邵泽志&#xff09;, Tangw…

XML解析库tinyxml2库使用详解

XML语法规则介绍及总结-CSDN博客 TinyXML-2 是一个简单轻量级的 C XML 解析库,它提供了一种快速、高效地解析 XML 文档的方式。 1. 下载地址 Gitee 极速下载/tinyxml2 2. 基本用法 下面将详细介绍 TinyXML-2 的主要使用方法: 2.1. 引入头文件和命名空间 #i…

Docker 国内镜像源更换

实现 替换docker 镜像源 前提要求 安装 docker docker-compose 参考创建一键更换docker国内源 vim /docker_daemon.sh #!/bin/bash # -*- coding: utf-8 -*- # Author: make.han # Email: CIASM@CIASM # Date: 2024/06/07 # docker daemon.jsondaemon_json_file="/et…

js 选择一个音频文件,绘制音频的波形,从右向左逐渐前进。

选择一个音频文件&#xff0c;绘制波形&#xff0c;从右向左逐渐前进。 完整代码&#xff1a; <template><div><input type"file" change"handleFileChange" accept"audio/*" /><button click"stopPlayback" :…