1

1、React.memo()是什么?

React 16.6.0版本钟主要更新了两个新的功能,帮助提高渲染性能:

  • React.memo()
  • React.lazy(): 使用 React Suspense 进行代码拆分和懒加载

本文只介绍React.memo()

React.memo()和PureComponent很相似,都是用来控制组件何时渲染的。我们都知道当组件props和state发生改变时,当前组件以及其子孙组件会重新渲染,但是有一些组件(纯文本组件)是不需要重新渲染的,这种不需要的组件被重新渲染会影响整体的渲染性能。

通过控制组件何时渲染可以帮助我们解决这个问题,在React中可以用来优化组件性能的方法大概有以下几种:

  • 组件懒加载(React.lazy(...)和<Suspense />)
  • PureComponent
  • shouldComponentUpdate(...){...}生命周期函数
  • React.memo

与PureComponent不同的是,React.memo()是一个高阶组件,用于函数组件,通过对前后props进行浅比较,如果前后props不一致,该组件将重新渲染,反之,不进行渲染,使用缓存中的组件。

function memo<T extends ComponentType<any>>(
 Component: T,
 propsAreEqual?: (prevProps: Readonly<ComponentProps<T>>, nextProps: Readonly<ComponentProps<T>>) => boolean
 ): MemoExoticComponent<T>;

memo函数第二个参数接收一个函数,该函数比较前后props是否一致。

2、React.memo使用前后比较

举个例子看看React.memo的使用,当不使用React.memo:

// Parent.tsx
import React, { useState } from 'react';
import Child from '../Child';

const Parent = () => {
 const [count, setCount] = useState(0);
 console.log('parent render update')
 return (
     <React.Fragment>
         <div>{count}</div>
         <button onClick={() => setCount(count + 1)}>++++</button>
         <Child msg='test'/>
     </React.Fragment>
 )
}

export default Parent;
// Child.tsx
import React from 'react';

const Child = (props) => {
 console.log('child render update');
 return <div>{props.msg}</div>
}

export default Child;

当父组件改变state时,Child组件也重新渲染了
image.png

当使用React.memo后

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

const Child = (props) => {
 console.log('child render update');
 return <div>{props.msg}</div>
}

export default React.memo(Child);

控制台打印结果
image.png

Child组件没有重新渲染,因为前后props没有改变。

3、类组件中控制渲染

3.1、shouldComponentUpdate

为了避免React组件的无用渲染,我们可以实现自己的shouldComponentUpdate生命周期函数。

当React想要渲染一个组件的时候,它将会调用这个组件的shouldComponentUpdate函数, 这个函数会告诉它是不是真的要渲染这个组件。

将Child组件改写一下就可以达到控制效果

import React from 'react';

class Child extends React.Component {
     shouldComponentUpdate(nextProps, nextState) {
         if (this.props.msg === nextProps.msg) {
             return false;
         }
         return true;
     }
     render() {
         return <div>test</div>
     }
}

export default Child;

image.png

3.2、PureComponent

PureComponent内部有监听props是否改变(浅比较),类组件继承PureComponent就可以控制渲染

import React from 'react';

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

export default Child;

image.png

4、总结

平常开发中应该对渲染性能有一定优化意识,React团队一直在致力于性能的提升,提出了很多新的API以及hooks,我们应该去了解、学习这些新知识,把开发做到极致!

参考:
https://segmentfault.com/a/11...
https://www.jianshu.com/p/929...


记得要微笑
1.9k 声望4.5k 粉丝

知不足而奋进,望远山而前行,卯足劲,不减热爱。