react 学习13实现 PureComponent

我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解了泪组件内部可以使用 shouldComponentUpdate 返回布尔值进行判断,本小节我们了解下基于该生命周期实现的另一个判断渲染机制的内置组件。

Component 示例

// src/index.js
class ClassCounter extends React.Component { // 这里我们先使用 Component 类
  render() {
    console.log('classcounter render')
    return <div>classCounter: {this.props.count} ---- {+new Date()}</div>
  }
}


class App extends React.Component {
  state = {
    number: 0
  }
  amountRef = React.createRef()

  handleClick = () => {
    this.setState({
      number: this.state.number + +this.amountRef.current.value
    })
  }
  render() {
    return <div>
      <ClassCounter count={this.state.number} />
      <input defaultValue={1} ref={this.amountRef} />
      <button onClick={this.handleClick}>+</button>
    </div>
  }
}

image.png

image.png

由上面的两个操作可知,即使子组件的属性值没有变化,页面已然发生了重新渲染。

PureComponent 示例

// src/index.js
class ClassCounter extends React.PureComponent {
  render() {
    console.log('classcounter render')
    return <div>classCounter: {this.props.count} ---- {+new Date()}</div>
  }
}

image.png

image.png

换成 PureComponent 后,我们在执行同样的操作,当 props.count 改变时,页面发生了渲染,当 count 没有变化时,页面没有渲染。

实现

// src/react.js

class PureComponent extends Component {
  // 我们知道 PureComponent 基于 shouldComponentUpdate 实现的是否渲染
  shouldComponentUpdate(nextProps, nextState) {
    return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState)
  }
}



// shallowEqual 是一个对比两个对象是否一样的浅比较方法,只比较第一层
// src/utils.js
export function shallowEqual(obj1, obj2) {
  // 地址一样
  if (obj1 === obj2) {
    return true
  }
  // 不是对象返回 false
  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(let k of keys1) {
    if (!obj2.hasOwnProperty(k) || obj1[k] !== obj2[k]) {
      return false
    }
  }
  return true
}

切换为自己的库,可以看到效果和原生库一样。本节内容同样不是很多,但对于理解 PureComponent 实现机制足够了,如有错误欢迎指正!

相关文章

一、前言 在组件方面react和Vue一样的,核心思想玩的就是组件...
前言: 前段时间学习完react后,刚好就接到公司一个react项目...
前言: 最近收到组长通知我们项目组后面新开的项目准备统一技...
react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...