react --- render持续调用解决方案

问题描述:

  • 在某个组件中.有可能频繁的取数据(但是数据未改变,因此不需要更新).
  • 数据的频繁请求会触发render函数,造成性能消耗
  • 模拟代码如下
export class CommentList extends Component {constructor(props) {super(props);this.state = {comments: []}}// 模拟频繁的获取新数据componentDidMount() {setInterval(() => {this.setState({comments:[{ body: '奇怪的栗子', author: 'odd marron'},{ body: '好吃的栗子', author: 'nice marron'}]})}, 1000)}render() {return (<div>{this.state.comments.map((c,i)=>(<Comment key={i} data={c} />))}</div>)}
}class Comment extends React.Component{console.log('render comment');render(){return (<div><p> {this.props.data.body} </p><p> --- {this.props.data.author} </p></div>)}
}

在这里插入图片描述

  • 可以看到,数据在未改变时,频繁的调用render

解决方案1

  • React 15.3之前(无PureComponent)
  • 使用shouldComponentUpdate
  • 在shouldComponentUpdate中判断当前body是否和传入的数据相等.
class Comment extends React.Component{shouldComponentUpdate(nextProps) {if(nextProps.data.body === this.props.data.body &&nextProps.data.author === this.props.data.author) {return false;}return true;}render() {return (<div><p> {data.body} </p><p> --- {data.author} </p></div>);}
}

解决方案2

  • PureComponent解决方案
  • 对上面代码修改后如下
import React, { Component } from 'react';// 容器组件
export class CommentList extends Component {constructor(props) {super(props);this.state = {comments: []};}componentDidMount() {setTimeout(() =>{this.setState({comments: [{ body: "奇怪的栗子" , author: "odd marron" },{ body: "好吃的栗子", author: "nice marron" }]});}, 1000)}render() {return (<div>{this.state.comments.map((c,i) => (<Comment key={i} {...c} />))}</div>);}
}
// 展示组件
class Comment extends React.PureComponent{render() {console.log('render comment');return (<div><p>{this.props.data.body}</p><p>--- {this.props.data.author}</p></div>)}
}

在这里插入图片描述

  • 此时数据为改变时 不更新.

注意:

  • 使用PureComponent时,其传递的参数只能是基本类型引用或简单的非多层嵌套对象
  • 原因见下面PureComponent源码:
import shallowEqual from './shallowEqual'
import Component from './Component'export default function PureComponent(props, context) {Component.call(this, props, context);
}PureComponent.prototype = Object.create(Component.prototype);
PureComponent.prototype.constructor = PureComponent;
PureComponent.prototype.isPureReactComponent = true;
PureComponent.prototype.shouldComponentUpdate = shallowCompare;function shallowCompare (nextProps, nextState) {return !shallowEqual(this.props, nextProps) ||!shallowEqual(this.state, nextState);
}export default function shallowEqual(objA, objB) {// 比较引用地址if(objA === objB){return true}// 只检查一层if(typeof objA !=='object' || obja === null || typeof objB !== 'objB' || objB === null) {return false}var keysA = Object.keys(objA);var keysB = Object.keys(objB);if(keysA.length !== keysB.length ){return false}for(var i = 0; i < keysA.length; i++ ){if(!objB.hasOwnproperty(keysA[i]) || objA[keysA[i]] !== objB[krysA[i]] ){return false;}}return true;
}
  • PureComponent 对shouldComponentUpdate进行设置.
  • 比较引用地址然后比较第一层…
  • 因此使用PureComponent时,应注意将对象结构出来使用

解决方案3

  • React.memo (React v16.6.0以上)
  • React.memo是个高阶函数
  • 更改上面Comment
const Comment = React.memo((props) => {console.log('render comment');return (<div><p>{props.body}</p><p> --- {props.author}</p></div>)
});

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

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

相关文章

Java 的工厂方法及代理模式

Java 的工厂方法及代理模式 工厂方法(FactoryMethod) 概述&#xff1a;定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。 适用性&#xff1a; 当一个类不知道它所必须创建的对象的类的时候当一个类希望由它的…

6、复制文件

复制文件 要求&#xff1a; 1、将原文件xxx.txt中的内容复制到新的文件里 2、新文件的文件名为xxx&#xff08;复制&#xff09;.txt&#xff0c;即原文件名复制进行命名 大框架&#xff1a; 1、输入想要复制的文件xxx.txt input() 2、创建一个文件xxx(复制).txt f1 open(&quo…

html的基本结构

标记语言&#xff0c;就是有标签结构的语言。 不管html文件有多复杂&#xff0c;它的基本结构 <元素 属性属性值 ... >内容</元素> 如果没有内容&#xff0c;可以这样写。 元素也被叫做标记。 案例 <p>是段落标记 <font size"" color"&quo…

react --- Hook的使用

Hook 是React16.8一个新增项,它可以让你在不编写class的情况下使用state以及其他的React特性特点: 无需修改组件结构的情况下复用状态逻辑将组件相互关联的部分拆分成更小的函数,复杂组件将变得更容易理解更简洁、更易理解的代码 使用Hook的栗子 import React, { useState …

POJ 1811 Prime Test (Rabin-Miller强伪素数测试 和Pollard-rho 因数分解)

题目链接 Description Given a big integer number, you are required to find out whether its a prime number. Input The first line contains the number of test cases T (1 < T < 20 ), then the following T lines each contains an integer number N (2 < N &…

Windows忘记mysql的密码

1、查看mysql的安装路径 show variables like "%char%"; 路径&#xff1a;C:\Program Files\MySQL\MySQL Server 5.7\ 2、关闭mysql服务 我的电脑--管理--服务于应用程序--服务--mysql--右键--停止 4、开始修改密码 1、打开dos窗口&#xff1a; widR 2.将目录mysqld.…

几种链表的优缺点比较

转载于:https://www.cnblogs.com/FengZeng666/p/9425117.html

node --- [跨域] 预检请求

简单请求 若满足所有下述条件&#xff0c;则该请求可视为“简单请求”&#xff1a; 使用下列方法之一&#xff1a; GET HEAD POST Content-Type: (仅当POST方法的Content-Type值等于下列之一才算做简单需求) text/plain multipart/form-data application/x-www-form-ur…

Java 的异常

Java 的异常 异常&#xff1a;在Java语言中&#xff0c;将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)Java程序在执行过程中所发生的异常事件可分为两类&#xff1a; Error: Java虚拟机无法解决的严重问题。如&#xff1a;JVM系统内部…

docker --- 将已有的项目发布到云端

[运行在win10] Dockerfile Docker根据该文件生成image文件 FROM node:8.4 COPY . /app WORKDIR /app RUN ["npm", "install"] EXPOSE 3000/tcp根据Dockerfile生成image 注意末尾有个.(英文的点)代表当前目录 docker image build -t koa-demo:0.0.1 .查…

linux --- 基础指令

基础命令 1、ls(list) 用法1: # ls 含义: 列出当前工作目录下所有的 文件/文件夹 的名称 用法2: # ls 路径 含义: 列出指定路径目录下所有的 文件/文件夹 的名称 用法3: # ls 选项 路径 含义: 以指定的格式来显示指定目录下文件夹的名称 栗子: # ls -l 路径 -->> 表…

验证码功能

验证码功能 1.安装captcha插件 (dj_login) D:\dj\dj_login>pip install django-simple-captcha Collecting django-simple-captchaUsing cached https://files.pythonhosted.org/packages/d7/f4/ea95b04ed3abc7bf225716f17e35c5a185f6100db4d7541a 46696ce40351/django-simp…

linux --- 进阶指令

进阶指令(重点) 1、df 指令 作用: 查看磁盘空间语法: # df -h 注: -h:以较高可读性的方式展示出来 2、free 指令 作用: 查看内存使用情况语法: # free -m 注: -m:以M的单位显示内存情况 -/ buffers/cache: free 代表真实可用的内存为 486 Mb Swap: 表示,临时将硬盘当作内存…

MFC对话框播放8位512*512的像素数据

关键代码&#xff1a; UINT playAllFrame(LPVOID lpParameter){//showOneFrame(0,TRUE);CMFCDialogDlg *mydlg (CMFCDialogDlg *) lpParameter;//获取原始数据文件CString selectPath;mydlg->GetDlgItemTextW(IDC_MFCEDITBROWSE,selectPath);string StrSelectPath(CW2A(sel…

linux --- 高级指令

高级指令 1、hostname 指令 作用: 操作(读取|操作)服务器的主机名语法1: # hostname (输出完整的主机名) 语法2: # hostname -f (输出当前主机中的FQDN) FQDN&#xff1a;(Fully Qualified Domain Name)全限定域名&#xff1a;同时带有主机名和域名的名称。 2、id 指令 作…

交换机老化测试和性能测试方法收集

说明&#xff1a;这是一个做交换机朋友给的一个方法&#xff0c;只做老化测试&#xff0c;不做压力满载测试。 我所理解的&#xff1a;老化测试是指在一定的时间内工作负荷之后&#xff0c;看有没有故障和不稳定的现象出现。 而对于压力测试&#xff0c;需要通过专业的测试设备…

【webGL入门2】点线面的绘制

用js绘制webGL的点&#xff1a; THREE.Vector3 function ( x, y, z ) {    //用THREE声明的变量都是全局变量。this.x x || 0;this.y y || 0;this.z z || 0;}; 注意&#xff1a;“||”&#xff08;或&#xff09;运算符&#xff0c;就是当xnull或者undefine时&#xff…

docker --- mysql的部署

MySQL部署 [1]查询本地镜像中是否含有 centos/mysql-57-centos7(我们用到的镜像) docker images[2] 拉取镜像 docker pull centos/mysql-57-centos7注: centos/mysql-57-centos7 是我们用到的镜像 [3] 创建容器 docker run -id --nametensquare_mysql -p 33306:3306 -e M…

node --- 连接mysql(docker环境) Sequelize库

mysql 数据库 [1] 首先配置 docker 环境 采用 docker-compose 方法 源码: /test-mysql/docker-compose.yml version: 3.1 services:mysql:image: mysqlcommand: --default-authentication-pluginmysql_native_passwordrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: examp…

Java-接口练习

Java-接口练习 编写2个接口&#xff1a;InterfaceA和InterfaceB&#xff1b;在接口InterfaceA中有个方法voidprintCapitalLetter()&#xff1b;在接口InterfaceB中有个方法void printLowercaseLetter()&#xff1b;然 后写一个类Print实现接口InterfaceA和InterfaceB&#xff0…