1、React.memo()是什么?
React 16.6.0版本钟主要更新了两个新的功能,帮助提高渲染性能:
- React.memo()
- React.lazy(): 使用 React Suspense 进行代码拆分和懒加载
本文只介绍React.memo()
React.memo()和PureComponent很相似,都是用来控制组件何时渲染的。我们都知道当组件props和state发生改变时,当前组件以及其子孙组件会重新渲染,但是有一些组件(纯文本组件)是不需要重新渲染的,这种不需要的组件被重新渲染会影响整体的渲染性能。
通过控制组件何时渲染可以帮助我们解决这个问题,在React中可以用来优化组件性能的方法大概有以下几种:
- 组件懒加载(React.lazy(...)和)
- 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组件也重新渲染了
当使用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);
控制台打印结果
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;
3.2、PureComponent
PureComponent内部有监听props是否改变(浅比较),类组件继承PureComponent就可以控制渲染
import React from 'react';
class Child extends React.PureComponent {
render() {
return <div>test</div>
}
}
export default Child;
4、总结
平常开发中应该对渲染性能有一定优化意识,React团队一直在致力于性能的提升,提出了很多新的API以及hooks,我们应该去了解、学习这些新知识,把开发做到极致!
参考
Web 性能优化: 使用 React.memo() 提高 React 组件性能
使用React.memo()来优化函数组件的性能
# 为什么要在函数组件中使用React.memo? - 七日打卡
React PureComponent 使用指南