react源码解析之Component和PureComponent

604 阅读2分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

在react v16.8.0版本之前,我们总是习惯大多数的使用 React.Component 来创建一个组件,那么 React.Component 是怎么来的呢?

React.Component

image.png

在上述源码中我们可以看到:

  • 创建了一个 Component的构造函数,并在其内部定义了 props context refs updater四个私有属性。
  • 接着在其原型对象上定义了 isReactComponent对象,setState方法,forceUpdate方法
  • 然后,我们在项目中使用es6的class类的继承来创建了react组件,如下:
import React from 'react';

export default class App extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        console.log(this, 'this对象')
        return (
            <div>app</div>
        )
    }
} 
  • 因为我们在创建自定义的组件时继承了 react.Component, 所以 我们可以在我们所创建的组件中使用 Component构造函数 原型对象上的方法和属性。看下图:

image.png

React.PureComponent

image.png 从上述源码中,我们可以看到:

  • const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy()) 此处没有直接继承Component,是为了避免继承 Component 的Constructor方法。目的是为了 减少一些内存的使用。
  • Object.assign(pureComponentPrototype, Component.prototype)此处做了优化 把 Component.prototype属性浅拷贝到pureComponentPrototype上 防止原型连拉长 导致方法的多层寻找 减少查询次数
  • 最后增加了 isPureReactComponent 属性,用来区分Component组件还是PureComponent

PureComponent 也是一种创建组件的方式。可以用来优化组件,通过减少不必要的更新,进而提升性能。其每次更新时会自动的对更新前后的props和state进行一个简单的对比,来决定是否进行更新。进行的是浅比较

  • 浅比较: 比较 基础类型的值,比较 引用类型的引用地址
  • PureComponent的浅比较源码中主要用的是 shallowEqual,而在该方法内部主要是利用了 Object.is()

image.png

Object.is()

  • Object.is()方法,是es6新增的一个方法。主要用来比较两个值是否**严格相等**,与严格比较运算符(===)的行为基本一致。
  • 不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true