React性能优化之React.PureComponent与React.memo

        众所周知,在React中,当父组件重新渲染时,正常情况下会对所有子孙级组件进行重新渲染。然而有时候子组件其实并未使用父组件的任何参数,这时候对子孙级的组件进行重新渲染是不必要的。这时候我们就需要使用React.PureComponent与React.memo进行性能优化了。

import Children from './Children';
import { useState } from 'react';

// 父组件
const Parent = () => {
  const [count, setCount] = useState<number>(0);

  return (
    <div style={
   
   { padding: 40 }}>
      <div>count: {count}</div>
      <button onClick={() => setCount((c) => ++c)}>count + 1</button>
      <Children />
    </div>
  );
};
export default Parent;
import React from 'react';

// 子组件
export default class Children extends React.Component {
  render() {
    console.log('Children 被重新绘制');
    return <div>Children component</div>;
  }
}

点击10次后的结果 :

 

一、React.PureComponent 

         React.PureComponent中内置shouldComponentUpdate方法,以浅层对比 prop 和 state 的方式来实现了该函数。在 props 和 state 较为简单时,可以使用React.PureComponent来防止组件不必要的更新。

        但是由于是浅层对比,如果 props 和 state 对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果,这时候推荐任然使用React.Component的方式通过手动写入shouldComponentUpdate来进行深层比较。

 比如,此时能防止Children 被重新绘制:

import React from 'react';

// 子组件
export default class Children extends React.PureComponent {
  render() {
    console.log('Children 被重新绘制');
    return <div>Children component</div>;
  }
}

点击10次后的结果 :

 

二、React.memo 

         React.memo为高阶组件,与React.PureComponent相似,但是其仅检查 props 变更。如果函数组件被 React.memo 包裹,但是组件内拥有 useState、useReducer 或 useContext 的 Hook,当 state 或 context 发生变化时,组件仍会重新渲染。

import React from 'react';

// 子组件
class Children extends React.Component {
  render() {
    console.log('Children 被重新绘制');
    return <div>Children component</div>;
  }
}
export default React.memo(Children);

 当然,其实React.memo是为了更好的解决函数类组件难以处理性能优化问题的痛点的:

import React from 'react';

// 子组件
const Children = () => {
  console.log('Children 被重新绘制');
  return <div>Children component</div>;
};
export default React.memo(Children);

点击10次后的结果 :

 

另外,React.memo支持通过第二个参数传入来控制对比过程,如果需要对props进行深层对比,则建议使用第二个参数:

import React from 'react';

// 子组件
const Children = () => {
  console.log('Children 被重新绘制');
  return <div>Children component</div>;
};

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

注意:

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

         结尾:在某些场景下,我们建议使用React.PureComponent 或者 React.memo()来进行性能优化。但并不是所有的组件都要引入的,因为自身浅对比这个过程也会有少许性能消耗,你需要根据项目的实际情况来决定是否使用。

参考:

React.PureComponent

React.memo 

猜你喜欢

转载自blog.csdn.net/qq_38629292/article/details/128571036