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; 当一个类不知道它所必须创建的对象的类的时候当一个类希望由它的…

Linux 和 Vim 常用命令整理

Sftp常用命令&#xff1a; lcd f&#xff1a;本地切换到 F盘 lpwd本地 当前目录 lls本地 文件列表 put 本地 上传文件到服务器(put输入后&#xff0c;回车会有弹窗&#xff0c;选择上传文件) get下载文件到本地 Linux命令&#xff1a; 1.文件夹的操作 1 pwd&#xff1a;显示…

Socket网络编程——C++实现

本代码可直接使用 根据TCP/IP三次握手&#xff0c;实验时可使用两台电脑&#xff0c;或者打开两个终端模拟通信。 服务器端&#xff1a; #include <iostream> #include <windows.h>using namespace std;#pragma comment(lib,"ws2_32.lib") //引用静态链接…

react --- 复合组件,传递属性

组件复合 复合组件给予你足够的灵活去定义组件的外观和行为,而且是以一种明确和安全的方式进行.如果组件间有公用的非UI逻辑,将它们抽取为JS模块导入使用而不是继承它/src/components/Composition.js // Dialog作为容器不关心内容和逻辑 function Dialog(props){return <d…

6、复制文件

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

Java 的内部类

Java 的内部类 在Java中&#xff0c;允许一个类的定义位于另一个类的内部&#xff0c;前者称为内部类&#xff0c;后者称为外部类。Inner class一般用在定义它的类或语句块之内&#xff0c;在外部引用它时必须给出完整的名称。 Inner class的名字不能与包含它的类名相同&#…

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.…

Java 的单例模式

Java 的单例模式 单例模式(Singleton) 单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象&#xff0c;我们首…

react --- 隔代传递参数的三种方式

组件跨层级通信 - Context 上下文提供一种不需要每层设置props就能跨多级组件传递数据的方式 方式1 Provider提供值Consumer来消费传递的值 import React from react;// 创建一个上下文 const Mycontext React.createContext(); const { Provider, Consumer } MyContext;…

bzoj 4898: [Apio2017]商旅【Floyd+分数规划+二分】

其实并不会分数规划 因为要最大化 ans总收益/总路程 &#xff0c;所以考虑二分答案&#xff0c;找到一条 ans<总收益/总路程 的回路。先预处理出d(i,j)为(i,j)最短路&#xff0c;w(i,j)为在i买某个物品在j卖出的最大收益&#xff08;最小为0&#xff09;。把式子变一下&…

几种链表的优缺点比较

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

node --- 模拟express实现一个简单的服务器

目标 使用express实现一个监听3000端口的http服务如下 const express require(express); const app express();app.get(/, (req, res) > {res.end(Hello Express); }) app.get(/users,(req, res)>{res.end(JSON.stringify({name: abc})) }) app.listen(3000, ()>{…

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 .查…

传递动态内存

一、内存分配分类 1.从静态存储区域分配。内存在程序编译的时候就已经分配好&#xff0c;这块内存在程序的整个运行期间都存在。例如全局变量&#xff0c;static 变量。 2.在栈上创建。在执行函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执行结…

linux --- 基础指令

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