react组件性能优化方案

发表于:2019-06-01

这篇主要介绍 pureComponentReact.memo API特性可以给组件带来性能提升。

pureComponent是什么?

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

如果还不是很理解,只要记住下面几点就够了:

  • 纯组件
  • 用于子组件
  • 只能在class中使用

实战

创建一个子组件 Child.jsx, 并使用了PureComponent,只做了一件事输出一个随机数

import React from 'react';

class Child extends React.PureComponent {
  render() {
    return (
      <div>{ Math.random() }</div>
    )
  }
}

export default Child;

创建一个父组件 Parent.jsx, 也只做一件事情,每点击一次按钮让count自增

import React from 'react';
import Child from './Child';

class Parent extends React.Component {
  state = {
    count: 0
  };

  handleClick = () => {
    this.setState((prevState) => {
      return { count: prevState.count + 1 };
    })
  }

  render() {
    return (
      <div>
        <p>{ this.state.count }</p>
        <button onClick={this.handleClick}>count++</button>
        <Child></Child>
      </div>
    )
  }
}

export default Parent;

将上面代码执行后的效果如下:

父组件count自增的同时render也发生了变化,注意的是虽然父组件重新render,但是子组件却未重新触发render, 这就是 PureComponent 的所在魅力。

如果子组件不使用 PureComponent 会发生什么呢? 将子组件代码改造下

// Child.jsx
import React from 'react';

class Child extends React.Component {
  render() {
    return (
      <div>{ Math.random() }</div>
    )
  }
}

export default Child;

再次执行,效果如下:

可以看到,如果不使用 PureComponent , 当父组件重新render 也会导致子组件重新render。这就是 PureComponentComponent 的主要区别。

使用pureComponent注意事项

  • pureComponent仅作对象的浅层比较
  • 确保所有子组件也都是“纯”的组件

React.memo是什么?

React.memo是一个高阶组件, 在16.6中新增的API,与 PureComponent 相似,用于弥补函数式组件。

PureComponent 的唯一区别就是可以实现 shouldComponentUpdate(), 也就是深层比较。

使用方法如下:

// Child.jsx
import React from 'react';

const Child = function () {
  return (
    <div>{ Math.random() }</div>
  )
}

export default React.memo(Child);

上面代码执行结果与 PureComponent 没有丝毫差异。

深层比较

// Child.jsx
import React from 'react';

const Child = function () {
  return (
    <div>{ Math.random() }</div>
  )
}

export default React.memo(Child, function(prevProps, nextProps) {
  /*
    如果把 nextProps 传入 render 方法的返回结果与
    将 prevProps 传入 render 方法的返回结果一致则返回 true,
    否则返回 false
  */
 if (prevProps.count === nextProps.count) {
   return true;
 }
 return false;
});

注意事项

与 class 组件中 shouldComponentUpdate() 方法不同的是,如果 props 相等,areEqual 会返回 true;如果 props 不相等,则返回 false。这与 shouldComponentUpdate 方法的返回值相反。

总结

性能优化是必不可或缺的一部分,在以往函数式组件中实现类似 PureComponent 特性会非常麻烦,现在官方有了API,可以让函数式组件更加的流行,配合Hooks简直无敌。当然了,也不建议所有的开发者都迁移函数式组件开发,每个场景有每个使用方法的好处。

React
广告