概述
如果你经常使用 PureComponent
或 shouldComponentUpdate
进行性能优化的时候,那么一定对纯函数组件(SFC 组件)缺失这样的功能而感觉不爽,甚至有时候不得不对有些复杂的组件进行一层包装,包装成类组件。
现在,React
官方终于提供了对这个功能的支持。在 React v16.6.0 新引入了一个高阶组件 React.momo
,它的作用类似于 React.PureComponent
但是是作用在纯函数组件(SFC 组件)上的。
const MyComponent = React.memo(function MyComponent(props) { |
也就是说,在 props 没有改变的情况下,Reactc将跳过重新渲染组件,而是重用最近一次的渲染结果。
自定义比较函数
当然,与 React.PureComponent
一样,在默认情况下,它只会浅比较 props 对象中的复杂对象。
如果要更加准确的控制比较的结果,还可以提供自定义的比较函数作为 React.momo
的第二个参数。
function MyComponent(props) { |
注意,这个自定义的比较函数和 shouldComponentUpdate()
对返回结果的处理正好相反,也就是说两次的 props 相同的时候返回 true,不同则返回 false。返回 true 会阻止更新,使用上次渲染的结果,而返回 false 则重新渲染。
需要注意的是,根据官方文档,这个函数仅仅被定义为进行性能优化,不要出于业务逻辑的需要使用它来阻止更新,否则可能造成一些问题。
This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs.
自己实现
知道了怎么用,以及它的原理,也可以来写一下实现:
使用类包装
这是最简单的一种方式,通过将函数式组件包装成为类组件:
const momo = (sfcRender, compareFunc) => { |
使用函数缓存
另一种实现方式是将相关数据缓存到函数上。
const momo = (sfcRender, compareFunc) => { |
注意,这两种实现仅供参考。这两种方式如果使用在单个的组件上,则其行为一致。但是,当应用到多个组件上时,具有较大的行为差异。第一种方式由于每次在使用的时候都生成了一个新的示例,所以仅在每次父组件更新时,才会触发比较判断是否更新。第二种方式由于是函数的实现方式,所以当首次渲染渲染多个包装过的函数式组件时,即进行判断。