博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React中的Component 和 PureComponent
阅读量:7226 次
发布时间:2019-06-29

本文共 3482 字,大约阅读时间需要 11 分钟。

React.ComponentReact.PureComponent很相似,两则的区别在于,PureComponent类帮我们以浅比较的方式对比propsstate,实现了shouldComponentUpdate()函数,在某些情况下,使用PureComponent可以减少render函数的执行,提升性能。

PureComponent能够提升性能

当Index组件继承Component

  1. 初次渲染时控制台会依次打印"constructor"、"render";

  2. 当第一次点击按钮更新state时,控制台会依次打印"render"、"componentDidUpdate";

  3. 后续每次触发点击事件,尽管flag的值没有变化,控制台还是会依次打印"render"、"componentDidUpdate",说明组件依然调用render()componentDidUpdate()函数,显然这是多余的,通常我们会手动重新实现shouldComponentUpdate(nextProps, nextState)函数判断stateprops的状态再来决定是否需要重新渲染

import React from 'react';class Index extends React.PureComponent{  constructor(props) {    super(props);    this.state = {      flag:false    };    console.log('constructor');  }  changeState = () => {    this.setState({      flag: true    })  };  render() {    console.log('render');    return (      
{this.state.flag.toString()}
); } componentDidUpdate() { console.log("componentDidUpdate") }}export default Index;复制代码

当Index组件继承PureComponent

  • 初次渲染和第一次点击按钮更新state时控制台输出同上面继承Component一样没有变化

  • 后续每次触发点击事件,控制台无输出, 省去执行render函数生成虚拟DOM,进行DIFF算法比较等后续操作

if (this._compositeType === CompositeTypes.PureClass) {  shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState);}复制代码

PureComponent默认实现的shouldComponentUpdate()方法使用的是浅比较: 即值的比较或引用的比较, 不会进行深层次的对比,所以当propsstate的值是引用类型时,即使对象的值改变了,但是对象的引用没变

import React from 'react';class IndexPage extends React.PureComponent{  constructor(props) {    super(props);    this.state = {      arr: [1,2,3,4,5]    };  }  changeArr = () => {    let {arr} = this.state    arr.pop()    this.setState({      arr    })    console.log("changeArr", arr)  };  render() {    const { arr } = this.state    console.log('render', arr);    return (      
    { arr.map(item =>
  • {item}
  • ) }
); } componentDidUpdate() { console.log("componentDidUpdate") }}export default IndexPage;复制代码
  1. 初次渲染时控制台会打印 render (5) [1, 2, 3, 4, 5]
  2. 当点击pop按钮时控制台会依次打印 changeArr (4) [1, 2, 3, 4]changeArr (4) [1, 2, 3] ...... 但是render函数不执行, 因为PureComponent实现的shouldComponentUpdate()认为值的引用没有变,故不执行后续的操作,只有在引用改变的情况下函数才会返回true

PureComponent也会影响子组件

下面例子中的render函数只会在刚创建的时候执行一次, 后续的点击按钮操作,由于PureComponent中的ShouldComponentUpdate()执行浅比较(对象值的引用没变),不会触发render函数的执行,其子组件也不会更新。

import React from 'react';import Item from './Item'class IndexPage extends React.PureComponent{  constructor(props) {    super(props);    this.state = {      arr: [1,2,3,4,5]    };  }  changeArr = () => {    let {arr} = this.state    arr.pop()    this.setState({      arr    })    console.log("changeArr", arr)  };  render() {    const { arr } = this.state    console.log('render', arr);    return (      
); } componentDidUpdate() { console.log("componentDidUpdate") }}export default IndexPage;复制代码
// Item.jsimport React, { Fragment, Component } from 'react'class Index extends Component {  render() {    const { arr } = this.props;    console.log("children", arr)    return (      
{ arr.map(item =>
  • {item}
  • ) }
    ) }}export default Index;复制代码

    总结

    1. PureComponent已经用浅层对比propsstate的方式替我们实现了shouldComponentUpdate(), 不仅能影响自身,还会影响其子组件;
    2. PureComponent 某些情况下(propsstate的值不经常变动, 因为浅比较也会耗时)可以提升性能;
    3. 继承自Component中的组件shouldComponentUpdate()默认情况下总是返回true;

    转载于:https://juejin.im/post/5d00e2ed51882520724c9094

    你可能感兴趣的文章
    能力工场--关于在JavaScript中使用EL表达式的问题
    查看>>
    NFS服务器设置
    查看>>
    s:iterator 中的status 使用方法
    查看>>
    cocos2d-x 源码剖析系列
    查看>>
    IT系统架构设计
    查看>>
    Nginx虚拟主机配置实践(一)
    查看>>
    细谈Spring(一)spring简介
    查看>>
    网络工程师的面试题
    查看>>
    nginx启动脚本
    查看>>
    常用输入法框架简介
    查看>>
    记录新机房建设。20130629
    查看>>
    安装ntop
    查看>>
    ssh远程登录讲解
    查看>>
    mysql的备份脚本
    查看>>
    linux下mysql的root密码忘记解决方法
    查看>>
    7.索引的性能分析
    查看>>
    在 Delphi 下使用 DirectSound (17): 频率均衡效果器 IDirectSoundFXParamEq8
    查看>>
    文件操作命令一cp 2
    查看>>
    Multi-Mechanize工程目录结构说明
    查看>>
    halt
    查看>>