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的基础上复制出来一个新数组,所以引用地址当然变啦)

原文地址:https://www.cnblogs.com/adoctors/p/10797672.html

时间: 2024-10-07 13:48:21

React.Component 与 React.PureComponent(React之性能优化)的相关文章

002-and design-dva.js 知识导图-01JavaScript 语言,React Component

一.概述 参看:https://github.com/dvajs/dva-knowledgemap react 或 dva 时会不会有这样的疑惑: es6 特性那么多,我需要全部学会吗? react component 有 3 种写法,我需要全部学会吗? reducer 的增删改应该怎么写? 怎么做全局/局部的错误处理? 怎么发异步请求? 怎么处理复杂的异步业务逻辑? 怎么配置路由? 二.JavaScript 语言 2.1.变量声明 const 和 let 不要用 var,而是用 const 和

React.js Tutorial: React Component Lifecycle

Introduction about React component lifecycle. 1 Lifecycle A React component in browser can be any of the following three statuses: mounted, update and unmounted. So React component lifecycle can be divided into three phases according to these statuse

React性能优化之PureComponent 和 memo使用分析

前言 关于react性能优化,在react 16这个版本,官方推出fiber,在框架层面优化了react性能上面的问题.由于这个太过于庞大,我们今天围绕子自组件更新策略,从两个及其微小的方面来谈react性能优化. 其主要目的就是防止不必要的子组件渲染更新. 子组件何时更新? 首先我们看个例子,父组件如下: import React,{Component} from 'react'; import ComponentSon from './components/ComponentSon'; im

react性能优化要点

1.减少render方法的调用 1.1继承React.PureComponent(会自动在内部使用shouldComponentUpdate方法对state或props进行浅比较.)或在继承自React.Component类型的组件中使用shouldComponentUpdate方法来决定render方法是否被调用. 使用浅比较时,如果是对象类型就会出问题,因此最好是使用immutable类型.<immutable在性能优化中的作用> 1.2在调用组件时,如果某个属性值是函数,避免使用箭头函数

React组件性能优化

转自:https://segmentfault.com/a/1190000006100489 React: 一个用于构建用户界面的JAVASCRIPT库. React仅仅专注于UI层:它使用虚拟DOM技术,以保证它UI的高速渲染:它使用单向数据流,因此它数据绑定更加简单:那么它内部是如何保持简单高效的UI渲染呢? React不直接操作DOM,它在内存中维护一个快速响应的DOM描述,render方法返回一个DOM的描述,React能够计算出两个DOM描述的差异,然后更新浏览器中的DOM. 就是说R

react+redux渲染性能优化原理

大家都知道,react的一个痛点就是非父子关系的组件之间的通信,其官方文档对此也并不避讳: For communication between two components that don't have a parent-child relationship, you can set up your own global event system. Subscribe to events in componentDidMount(), unsubscribe in componentWillU

React 组件性能优化探索实践

转自:http://www.tuicool.com/articles/Ar6Zruq React本身就非常关注性能,其提供的虚拟DOM搭配上Diff算法,实现对DOM操作最小粒度的改变也是非常的高效.然而其组件渲染机制,也决定了在对组件进行更新时还可以进行更细致的优化. react组件渲染 react的组件渲染分为初始化渲染和更新渲染. 在初始化渲染的时候会调用根组件下的所有组件的render方法进行渲染,如下图(绿色表示已渲染,这一层是没有问题的): 但是当我们要更新某个子组件的时候,如下图的

React组件性能优化总结

性能优化的思路 影响网页性能最大的因素是浏览器的重排(repaint)和重绘(reflow). React的Virtual DOM就是尽可能地减少浏览器的重排和重绘. 从React渲染过程来看,如何防止不必要的渲染是解决问题的关键. 性能优化的具体办法 1. 尽量多使用无状态函数构建组件 无状态组件只有props和context两个参数.它不存在state,没有生命周期方法,组件本身即有状态组件构建方法中的render方法. 在合适的情况下,都应该必须使用无状态组件.无状态组件不会像React.

关于React性能优化

这几天陆陆续续看了一些关于React性能优化的博客,大部分提到的都是React 15.3新加入的PureComponent ,通过使用这个类来减少React的重复渲染,从而提升页面的性能.使用过React的朋友都知道,React组件只有在state和props发生改变时才会触发render,如果state和props没有发生改变,render就不执行.通常在写页面的时候,如果没有使用PureComponent类,为了避免重复渲染而产生的性能问题,我们会使用shouldComponentUpdat