问题描述:

  • 在某个组件中.有可能频繁的取数据(但是数据未改变,因此不需要更新).
  • 数据的频繁请求会触发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>)
});

react --- render持续调用解决方案相关推荐

  1. react组件卸载调用的方法_好程序员web前端培训分享React学习笔记(三)

    好程序员web前端培训分享React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处 ...

  2. react render没更新_web前端教程分享React学习笔记(一)

    web前端教程分享React学习笔记(一),React的起源和发展:React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写 ...

  3. [react] render方法的原理你有了解吗?它返回的数据类型是什么?

    [react] render方法的原理你有了解吗?它返回的数据类型是什么? render的第一个参数通过babel转为React.createElement,后者根据参数类型的不同调用不同的内部方法来 ...

  4. react render相关 【类组件、函数组件 】

    [类组件] 大概就是如果是class的写法,并且extends React.component 就要手动写render [函数组件] 如果是const App = ()=> {} 那么就酸函数组 ...

  5. TypeScript 3.0下react默认属性DefaultProps解决方案

    TypeScript 3.0下react默认属性DefaultProps解决方案 参考文章: (1)TypeScript 3.0下react默认属性DefaultProps解决方案 (2)https: ...

  6. ReactDom.render和React.render的区别

    这个是react最新版api,也就是0.14版本做出的改变.主要是为了使React能在更多的不同环境下更快.更容易构建.于是把react分成了react和react-dom两个部分.这样就为web版的 ...

  7. [react] render在什么时候会被触发?

    [react] render在什么时候会被触发? 在 React 中,只要执行了 setState 方法,就一定会触发 render 函数执行: 组件的 props 改变了,不一定触发 render ...

  8. [react] render函数中return如果没有使用()会有什么问题?

    [react] render函数中return如果没有使用()会有什么问题? 我们在使用JSX语法书写react代码时,babel会将JSX语法编译成js,同时会在每行自动添加分号(:),如果retu ...

  9. Jenkins持续发布解决方案

    Jenkins持续发布解决方案 参考文章: (1)Jenkins持续发布解决方案 (2)https://www.cnblogs.com/facethesea/p/7978598.html (3)htt ...

最新文章

  1. 如何将深度学习模型部署到实际工程中?(分类+检测+分割)
  2. android广告页白屏_android 白屏
  3. openSSL命令、PKI、CA、SSL证书原理
  4. SQL必知必会-过滤数据
  5. rust socket 客户端例子
  6. pyboard使用心得记录-基于对sk6812的控制(欢迎补充)
  7. xsmax进入dfu模式_DFU模式是什么?苹果XR/XS Max的DFU模式进入与退出方法[多图]
  8. 马云请不动郭盛华的原因?原来背后还有更神秘的人物
  9. 计算机的游戏功能,游戏同步器功能介绍、作用讲解及使用方法
  10. Json文件简单读写
  11. 自然语言处理之新手上路
  12. m基于PSO粒子群优化的柔性制造系统AGV调度模型matlab仿真
  13. 2021南宁周赛!第一期题解
  14. 如何使用linux系统自带的led驱动
  15. Matplotlib多子图绘图后保存单个子图
  16. 风靡厦门的一种游戏你玩过吗?竟然发明者不是郑成功,而另有其人!
  17. 8. Django 模型(二)
  18. java jframe 图片_java中JFrame添加背景图片
  19. 缓存通俗解释_在超市购买牛奶解释了网络缓存
  20. 如何使Windows 11更快以获得良好的性能

热门文章

  1. bootstraptable控制分页_bootstrap table分页(前后端两种方式实现)
  2. eclipse软件有时会退出弹出一串错误弹框_修复iPhone上的iOS 13软件更新失败错误...
  3. html js坐标图,javascript – HTML5 Canvas沿着带坐标的路径拖动图像
  4. python slice类型_复合类型Slice python中的list
  5. python关闭浏览器删除session_Django操作session 的方法
  6. 显示mnist手写数字
  7. 显示/隐藏Mac系统中所有的隐藏文件
  8. rank()over 函数的使用
  9. 数据分析方法有哪些_数据分析方法
  10. Python字符串笔录