React.Component 与 React.PureComponent(React之性能优化)
前言
先说说 shouldComponentUpdate
提起React.PureComponent,我们还要从一个生命周期函数 shouldComponentUpdate 说起,从函数名字我们就能看出来,这个函数是用来控制组件是否应该被更新的。
React.PureComponent 通过prop和state的
浅对比来实现shouldComponentUpate()。
简单来说,这个生命周期函数返回一个布尔值。
如果返回true,那么当props或state改变的时候进行更新;
如果返回false,当props或state改变的时候不更新,默认返回true。
(这里的更新不更新,其实说的是执不执行render函数,如果不执行render函数,那自然该组件和其子组件都不会重新渲染啦)
重写shouldComponentUpdate可以提升性能,它是在重新渲染过程开始前触发的。当你明确知道组件不需要更新的时候,在该生命周期内返回false就行啦!
下面是一个重写shouldComponentUpdate的例子:
class CounterButton extends React.Component {
state={
count: 1
}
shouldComponentUpdate(nextProps, nextState) {
const {color}=this.props;
const {count}=this.state;
if (color !== nextProps.color) {
return true;
}
// 重写shouldComponentUpdate若将此处count相关逻辑注释则count变化页面不渲染
// if (count !== nextState.count) {
// return true;
// }
return false;
}
render() {
const {color}=this.props;
const {count}=this.state;
return (
<button
style={{color}}
onClick={() => this.setState(state => ({count: state.count + 1}))}
>
Count: {count}
</button>
);
}
}
React.Component 与 React.PureComponent
言归正传,接下来说我们今天要讨论的React.Component 与 React.PureComponent。
通常情况下,我们会使用ES6的class关键字来创建React组件:
class MyComponent extends React.Component {
// some codes here ...
}
但是,你也可以创建一个继承React.PureComponent的React组件,就像这样
class MyComponent extends React.PureComponent {
// some codes here
}
那么,问题来了,这两种方式有什么区别呢?
继承PureComponent时,不能再重写shouldComponentUpdate,否则会引发警告(报错截图就不贴了,怪麻烦的)
Warning: CounterButton has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.
继承PureComponent时,进行的是浅比较,也就是说,如果是引用类型的数据,只会比较是不是同一个地址,而不会比较具体这个地址存的数据是否完全一致
class ListOfWords extends React.PureComponent {
render() {
return <div>{this.props.words.join(',')}</div>;
}
}
class WordAdder extends React.Component {
state = {
words: ['adoctors','shanks']
};
handleClick = () => {
const {words} = this.state;
words.push('tom');
this.setState({words});
console.log(words)
}
render() {
const {words}=this.state;
return (
<div>
<button onClick={this.handleClick}>click</button>
<ListOfWords words={words} />
</div>
);
}
}
上面代码中,无论你怎么点击按钮,ListOfWords渲染的结果始终没变化,原因就是WordAdder的word的引用地址始终是同一个。

浅比较会忽略属性或状态突变的情况,其实也就是,数据引用指针没变而数据被改变的时候,也不新渲染组件。但其实很大程度上,我们是希望重新渲染的。所以,这就需要开发者自己保证避免数据突变。
如果想使2中的按钮被点击后可以正确渲染ListOfWords,也很简单,在WordAdder的handleClick内部,将 const words = this.state.words;
改为const words = this.state.words.slice(0);(这时的words是在原来state的基础上复制出来一个新数组,所以引用地址当然变啦)

React.Component 与 React.PureComponent(React之性能优化)的更多相关文章
- React性能优化总结
本文主要对在React应用中可以采用的一些性能优化方式做一下总结整理 前言 目的 目前在工作中,大量的项目都是使用react来进行开展的,了解掌握下react的性能优化对项目的体验和可维护性都有很大的 ...
- 转载 React.createClass 对决 extends React.Component
先给出结论,这其实是殊途同归的两种方式.过去我们一般都会使用 React.createClass 方法来创建组件,但基于 ES6 的小小语法糖,我们还可以通过 extends React.Compon ...
- 002-and design-dva.js 知识导图-01JavaScript 语言,React Component
一.概述 参看:https://github.com/dvajs/dva-knowledgemap react 或 dva 时会不会有这样的疑惑: es6 特性那么多,我需要全部学会吗? react ...
- React.js Tutorial: React Component Lifecycle
Introduction about React component lifecycle. 1 Lifecycle A React component in browser can be any of ...
- React的性能优化 - 代码拆分之lazy的使用方法
我们在某些网站上肯定看到过这样一种现象,页面上图片只有你滚动到那个位置附近的时候才会加载,否则就只占了个位,这就是延迟加载最普遍的应用场景. 我们react框架进行开发的时候也是一样,没有使用的组件是 ...
- React源码解析之React.Children.map()(五)
一,React.Children是什么? 是为了处理this.props.children(this.props.children表示所有组件的子节点)这个属性提供的工具,是顶层的api之一 二,Re ...
- React Tutorial: Basic Concept Of React Component---babel, a translator
Getting started with react.js: basic concept of React component 1 What is React.js React, or React.j ...
- React性能优化 PureComponent
为什么使用? React15.3中新加了一个 PureComponent 类,顾名思义, pure 是纯的意思, PureComponent 也就是纯组件,取代其前身 PureRenderMixin ...
- React性能优化之PureComponent 和 memo使用分析
前言 关于react性能优化,在react 16这个版本,官方推出fiber,在框架层面优化了react性能上面的问题.由于这个太过于庞大,我们今天围绕子自组件更新策略,从两个及其微小的方面来谈rea ...
随机推荐
- CGAffineTransformMake 矩阵变换 的运算原理(转)
1.矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty; }; CGAffineTransform CGAff ...
- opennebula 添加kvm主机日志
Sun Sep :: [ReM][D]: Req: UID: HostDelete invoked, Sun Sep :: [ReM][D]: Req: UID: HostDelete result ...
- Linux虚拟机磁盘扩容
扩容步骤如下: 1.添加一块物理硬盘 2.fdisk将硬盘分区,选primary分区,创建1-4个 3.分区类型格式化,选择t,输入LVM代号 4.分好后按w退出 如果是调整原有逻辑卷大小,则先调整原 ...
- JMeter下载及安装配置完整版
特别需要注意的时,jdk版本和jmeter版本匹配问题. Jdk1.8对应apache-jmeter-3.3 Jmeter下载及安装配置 本文是在win7环境下安装使用jmeter,jmeter可以运 ...
- Java代码加密与反编译(二):用加密算法DES修改classLoader实现对.class文件加密
Java代码加密与反编译(二):用加密算法DES修改classLoader实现对.class文件加密 二.利用加密算法DES实现java代码加密 传统的C/C++自动带有保护机制,但java不同,只要 ...
- octomap相关
转载自http://blog.csdn.net/linuxarmsummary/article/details/50924947 什么是octomap? RGBD SLAM的目的有两个:估计机器人的轨 ...
- qt下的跨目录多工程编译(转)
这里要编译的工程包含一个库和一个可执行文件.可执行文件依赖于库,所以要先编译库,编译后库放在lib目录里面,可执行文件放在bin目录里面. 目录结构如下: 全局的工程文件complex.pro在工程根 ...
- php eval
// Our PHP code inside a variable $phpCode = ' class Foo { private $name; public function __construc ...
- SpringMVC的问题No mapping found for HTTP request with URI
做了一个屏蔽进数据库的操作: Applicaition.xml配置: <?xml version="1.0" encoding="UTF-8"?> ...
- ecshop后台登录频繁自动退出问题终极解决方法集锦
ecshop后台登录后,有时候会自动退出,而且还会很频繁,有的是后台操作两下就莫名退出了,有的是恰好三分钟左右登出.这让管理员很恼火,严重影响了后台使用.对于这一问题,网络上可给的解决方法各有不同.千 ...