React中PureComponent原理

PureComponent 会对 propsstate 进行浅层比较,并减少了跳过必要更新的可能性。

React.PureComponentReact.Component 很相似。两者的区别在于 React.Component 并未实现 shouldComponentUpdate(),而 React.PureComponent中以浅层对比 propstate 的方式来实现了该函数。

如果赋予 React 组件相同的 propsstaterender() 函数会渲染相同的内容,那么在某些情况下使用 React.PureComponent 可提高性能。

import React from 'react';
import ReactDOM from 'react-dom';

class Counter extends React.Component {
  state = {
    count: 0
  }
  handleClick = () => {
    this.setState({ count: this.state.count + 1 })
  }
  render() {
    return (
      <div>
        <Title title='计数器'></Title>
        <span>{this.state.count}</span>
        <button onClick={this.handleClick}>+1</button>
      </div>
    );
  }
}

class Title extends React.Component {
  render() {
    // 检查是否多次打印
    console.log('Title render')
    return (
      <p>{this.props.title}</p>
    );
  }
}

ReactDOM.render(<Counter />, document.getElementById('root'))

上面演示的代码中 Counter 组件中使用了 Title 组件,Counter 组件每次修改状态都会导致 Title 组件重新渲染。可以看到 console 语句多次打印出 Title render。如果不想让 Title 组件多次渲染,就需要让 Title 组件继承 PureComponent 组件。

开始使用

  1. 类组件使用 PureComponent
import React from 'react';
import ReactDOM from 'react-dom';

class Counter extends React.Component {
  state = {
    count: 0
  }
  handleClick = () => {
    this.setState({ count: this.state.count + 1 })
  }
  render() {
    return (
      <div>
        <Title title='计数器'></Title>
        <span>{this.state.count}</span>
        <button onClick={this.handleClick}>+1</button>
      </div>
    );
  }
}

class Title extends React.PureComponent {
  render() {
    console.log('Title render')
    return (
      <p>{this.props.title}</p>
    );
  }
}

ReactDOM.render(<Counter />, document.getElementById('root'))
  1. 函数组件使用 memo
class Counter extends React.Component {
  state = {
    count: 0
  }
  handleClick = () => {
    this.setState({ count: this.state.count + 1 })
  }
  render() {
    return (
      <div>
        <Title title='计数器'></Title>
        <span>{this.state.count}</span>
        <button onClick={this.handleClick}>+1</button>
      </div>
    );
  }
}
const Title = React.memo(props => {
  console.log('Title render')
  return <p>{props.title}</p>
})
  1. memo 的原理
function memo (Func) {
  class Proxy extends React.PureComponent {
    render() {
      return (
        <Func {...this.props} />
      );
    }
  }
  return Proxy
}
  1. PureComponent 的原理

import React, { Component } from 'react';

function shallowEqual(obj1, obj2) {
  if (obj1 === obj2) {
    return true
  }
  if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
    return false
  }
  let keys1 = Object.keys(obj1)
  let keys2 = Object.keys(obj2)
  if (keys1.length !== keys2.length) {
    return false
  }
  for (const key of keys1) {
    if (!obj2.hasOwnProperty(key) || obj1[key] !== obj2[key]) {
      return false
    }
  }
  return true
}

class PureComponent extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState)
  }
  render() {
    return this.props.children;
  }
}

export default PureComponent;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 12,678评论 1 33
  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 4,690评论 0 1
  • 3. JSX JSX是对JavaScript语言的一个扩展语法, 用于生产React“元素”,建议在描述UI的时候...
    pixels阅读 7,898评论 0 24
  • 说在前面 关于 react 的总结过去半年就一直碎碎念着要搞起来,各(wo)种(tai)原(lan)因(le)。心...
    陈嘻嘻啊阅读 11,805评论 7 41
  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 12,460评论 2 35