react 学习(13)实现 PureComponent

118 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

我们知道 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>
  }
}

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

PureComponent 示例

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

换成 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 实现机制足够了,如有错误欢迎指正!