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.pswp.cn/news/250580.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250580.shtml
英文地址,請注明出處:http://en.pswp.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 路徑 -->> 表…