【React性能优化】父组件渲染如何避免子组件不必要的渲染

类组件:

  1. 需要注意的点是,尽量避免事件处理函数直接返回,如以下写法:
class LoggingButton extends React.Component {handleClick() {console.log('this is:', this);}render() {// 此语法确保 `handleClick` 内的 `this` 已被绑定。return (<button onClick={() => this.handleClick()}>Click me</button>);}
}

此语法问题在于每次渲染 LoggingButton 时都会创建不同的回调函数。在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。我们通常建议在构造器中绑定或使用 class fields 语法来避免这类性能问题

应该用以下写法来写
1).构造器中绑定

class Toggle extends React.Component {constructor(props) {super(props);this.state = {isToggleOn: true};// 为了在回调中使用 `this`,这个绑定是必不可少的this.handleClick = this.handleClick.bind(this);}handleClick() {this.setState(prevState => ({isToggleOn: !prevState.isToggleOn}));}render() {return (<button onClick={this.handleClick}>{this.state.isToggleOn ? 'ON' : 'OFF'}</button>);}
}

2).class fields 语法

class LoggingButton extends React.Component {// This syntax ensures `this` is bound within handleClick.handleClick = () => {console.log('this is:', this);};render() {return (<button onClick={this.handleClick}>Click me</button>);}
}
  1. 使用shouldComponentUpdate()
  2. 使用React.PureComponent 来代替手写 shouldComponentUpdate
    但它只进行浅比较(基本数据类型只比较值,复杂数据类型只比较引用地址),所以当 props 或者 state 某种程度是可变的话,浅比较可能会有遗漏。在给props重新赋值的时候,如果需要引起重新渲染,要赋一个新值,即引用地址需要改变

函数组件:

  1. React.memo - HOC(高阶组件)
import React from 'react';const ChildComponent = React.memo(function({ prop }) {// 子组件渲染逻辑
});export default ChildComponent;

也是对props进行浅比较,如果props没有改变,子组件就不重新渲染。当改变数组(对象)类型的props的时候记得返回一个全新的数组(对象),或者如果只在某些props改变的时候需要渲染,可以加上第二个参数(相当于PureComponent和shouldComponentUpdate的结合),如下,当areEqual为false的时候会触发渲染。

function MyComponent(props) {/* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {/*如果把 nextProps 传入 render 方法的返回结果与将 prevProps 传入 render 方法的返回结果一致则返回 true,否则返回 false*/
}
export default React.memo(MyComponent, areEqual);
  1. useMemo() 进行细粒度性能优化
    上面 React.memo() 的使用我们可以发现,最终都是在最外层包装了整个组件,并且需要手动写一个方法比较那些具体的 props 不相同才进行 re-render。

而在某些场景下,我们只是希望 component 的部分不要进行 re-render,而不是整个 component 不要 re-render,也就是要实现局部 Pure 功能。

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。

import { Button, Divider } from "antd";
import React, { useState, useMemo } from "react";const Parent = () => {
const [num, setNum] = useState(0);const clickHadler = () => {
setNum(num + 1)
}// 使用 useMemo 缓存计算的结果
const computeResult = useMemo(() => {for(let i = 0; i < 10000; i++) {}console.log('进行了大量计算')
}, [])return (
<>
{computeResult}
number值: {num}
<Button type='primary' onClick={() => clickHadler()}>
点击计算
</>
);
};export default Parent;
  1. useCallback
 const memoizedCallback = useCallback(() => {doSomething(a, b);},[a, b],
);

把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate)的子组件时,它将非常有用。

useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

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

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

相关文章

Flutter集成高德导航SDK(Android篇)(JAVA语法)

先上flutter doctor&#xff1a; flutter sdk版本为&#xff1a;3.19.4 引入依赖&#xff1a; 在app的build.gradle下&#xff0c;添加如下依赖&#xff1a; implementation com.amap.api:navi-3dmap:10.0.700_3dmap10.0.700navi-3dmap里面包含了定位功能&#xff0c;地图功能…

UML图的分类

uml图是用来展示大型软件工程之间的内部关系&#xff0c;如果只用代码表示&#xff0c;密密麻麻的谁看都头疼。 UML图分为结构图和行为图 .类图&#xff1a;一组对象&#xff0c;接口&#xff0c;协作和它们之间的关系 对象图&#xff1a;一组对象以及它们之间的关系 用例图…

Mysql在linux系统中定时备份

1. 创建备份脚本 #!/bin/bash# 设置数据库名、用户名和密码 DB_NAME"your_database_name" DB_USER"your_username" DB_PASSWORD"your_password"# 设置备份目录 BACKUP_DIR"/path/to/your/backup/directory"# 创建备份目录如果不存在 …

Kafka搭建(集群版)

Kafka单机版 部署前提 VMware环境 : 两台centos系统 Jdk包:jdk-8u202-linux-x64.tar.gz Kafka包:kafka_2.12-3.5.0.tgz Zookeeper包:apache-zookeeper-3.7.2-bin.tar.gz 百度网盘自取: 链接: https://pan.baidu.com/s/11EWuhBoSmH3musd_3Rgodw?pwde32t 提取码: e32t Kafka搭建…

运行程序报错died with <Signals.SIGKILL: 9>问题定位及解决方法

运行程序报错died with 报错 当我在运行程序时&#xff0c;报错&#xff1a; Traceback (most recent call last):File "/home/anaconda3/envs/scene_graph_benchmark/lib/python3.8/runpy.py", line 194, in _run_module_as_mainreturn _run_code(code, main_glo…

免密登录ssh

前言&#xff1a; 1.基于口令的认证&#xff08;password认证&#xff09;&#xff1a; 客户端向服务器发出password认证请求&#xff0c;将用户名和密码加密后发送给服务器&#xff0c;服务器将该信息解密后得到用户名和密码的明文&#xff0c;与设备上保存的用户名和密码进行…

香橙派AIpro开发板评测:部署yolov5模型实现图像和视频中物体的识别

OrangePi AIpro 作为业界首款基于昇腾深度研发的AI开发板&#xff0c;自发布以来就引起了我的极大关注。其配备的8/20TOPS澎湃算力&#xff0c;堪称目前开发板市场中的顶尖性能&#xff0c;实在令人垂涎三尺。如此强大的板子&#xff0c;当然要亲自体验一番。今天非常荣幸地拿到…

边界无限陈佩文:红蓝对抗安全演练常态化的各方分析

虽然常态化演练尚未正式开始&#xff0c;但我们仍然希望对各方的表现进行一些分析和预测&#xff0c;以辅助我们对市场的判断和决策。同时&#xff0c;也希望通过这些初步的见解&#xff0c;抛砖引玉&#xff0c;引发更多有价值的讨论和观点。 “船停在码头是最安全的&#xf…

Hi3861 OpenHarmony嵌入式应用入门--SNTP

sntp&#xff08;Simple Network Time Protocol&#xff09;是一种网络时间协议&#xff0c;它是NTP&#xff08;Network Time Protocol&#xff09;的一个简化版本。 本项目是从LwIP中抽取的SNTP代码&#xff1b; Hi3861 SDK中已经包含了一份预编译的lwip&#xff0c;但没有…

怎么把数据转换成百度k线图

要将数据转换成百度K线图&#xff0c;您需要按照百度K线图的要求对数据进行处理和格式化。以下是一个简单的示例&#xff0c;演示如何将数据转换成百度K线图的格式&#xff1a; python import json # 假设您有以下数据 data [ {"date": "2021-01-01"…

【Python123题库】#计算整数各位数字之和 #分类统计字符个数 #用户登录C #二分法求平方根B

禁止转载&#xff0c;原文&#xff1a;https://blog.csdn.net/qq_45801887/article/details/140079918 参考教程&#xff1a;B站视频讲解——https://space.bilibili.com/3546616042621301 有帮助麻烦点个赞 ~ ~ Python123题库 计算整数各位数字之和分类统计字符个数用户登录C…

Java基础之关键字

关键字 transient 被transient修饰的成员变量在序列化(serialization)时&#xff0c;值会被忽略&#xff0c;在反序列化时会被设为初始值(对象为null) synchronized 既可以修饰方法也可以修饰方法块&#xff0c;被synchronized修饰的代码块及方法&#xff0c;在同一时间只能…

nacos占位符配置

有的时候&#xff0c;我们的nacos会出现一个配置文件里&#xff0c;有多个配置项对应的值都是一样的&#xff0c;这个时候nacos就可以用到占位符${}进行参数配置。 auth:api1:host: http://aaa.comapi2:host: http://aaa.com可以将共同的参数提取出来统一配置&#xff0c;后期…

线程间的通信

文章目录 线程间的通讯技术就是通过等待和唤醒机制&#xff0c;来实现多个线程协同操作完成某一项任务&#xff0c;例如经典的生产者和消费者案例。等待唤醒机制其实就是让线程进入等待状态或者让线程从等待状态中唤醒&#xff0c;需要用到两种方法&#xff0c;如下&#xff1a…

Java中的内存数据库与缓存技术

Java中的内存数据库与缓存技术 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 内存数据库的概念与优势 1.1 什么是内存数据库&#xff1f; 内存数据库是…

python写的工具代码总结

目录 python画图&处理图片python增大图片的大小&#xff08;比如将几百K的照片增加到几mb&#xff09;解决python画图无法显示中文的问题python画折线图 & 一张图上三条折线 & 设置折线marker & chatgpt画折线图的提示词python将png格式的图片转换为jpg格式的图…

红蓝对抗下的内网横向移动渗透技术详解

一、利用Windows计划任务横向移动 Windows计划任务是一个非常实用的功能&#xff0c;可以帮助我们自动完成一些重复性的任务。比如&#xff0c;我们可以设定一个计划任务来自动备份文件、更新软件、执行脚本等,本文主要介绍了如何利用Windows计划任务进行横向渗透。 &#xf…

列举操作redis set的命令

Redis中的Redis中的Set是一种无序的Set是一种无序的、不包含重复元素的字符串集合。、不包含重复元素的字符串集合。操作Redis Set的命令非常丰富&#xff0c;下面列举了一些常用的命令&#xff1a; **S操作Redis Set的命令非常丰富&#xff0c;下面列举了一些常用的命令&#…

C#委托事件的实现

1、事件 在C#中事件是一种特殊的委托类型&#xff0c;用于在对象之间提供一种基于观察者模式的通知机制。 1.1、事件的发送方定义了一个委托&#xff0c;委托类型的声明包含了事件的签名&#xff0c;即事件处理器方法的签名。 1.2、事件的订阅者可以通过运算符来注册事件处理器…

Python基础小知识问答系列-过滤列表元素

1. 问题&#xff1a; 如何根据单一条件过滤列表的元素&#xff1f; 如何根据复杂条件过滤列表的元素&#xff1f; 2. 解决方式&#xff1a; 可以使用推导式生成器&#xff0c;进行单一条件的列表元素过滤&#xff0c;尤其是列表内容较多时; 也可以使用filter函数进行列…