type
status
date
slug
summary
tags
category
icon
password

React memo

纯组件

Pure Components:为相同的state和props呈现相同的输出。
  • 在函数式组件中,可以使用React.memo() 来实现纯组件
  • 在类组件中,使用extending React.PureComponent 而不是React.Component 可以让组件是一个纯组件

Memo

React.memo() : 1. 是一个高阶函数 2. 此API通过使用Object.is浅层比较来比较以前的props和新props,从而防止React在其父级重新渲染时重新渲染该组件,用于性能优化。 3. 使用时机:组件经常使用相同的props重新渲染,如果传递的props始终新的,没有使用memo 的必要,可以配合useMemo and useCallback 使用 4. 仅仅记忆父组件传递过来的props,与内部的state、使用到的上下文变量无关
 
参数:
  • 一般情况下,memo会自动进行新旧props的浅比较,当props不同的时时候会执行第一个参数,也就是传入的函数(如上代码示例)
  • 特殊情况下,可以自定义第二个参数,自定义比较函数arePropsEqual,当该函数返回true的时候才会执行(如下代码示例),注意尽量不要在arePropsEqual 中进行深比较,因为它会比较每个props,包含函数,Functions often close over the props and state of parent components.从而导致出现问题
 
实际例子
notion image
notion image
 

使用建议

大量使用Memo会使代码的可读性变低,可以通过遵循以下几条原则来避免大量的memoization处理:
  1. 嵌套的子组件是一个JSX,不传递props
  1. 优先选择本地状态,必要时不要将状态上移。例如,不要在全局状态库中保留瞬时状态,如表单、项目是否悬停在树的顶端等。
  1. 尽量让渲染逻辑更pure,而不是添加更多的memoization
  1. 避免不必要的更新状态的 Effects ,Effects 的更新链会导致组件重新渲染
  1. 尽量移除 Effects 中的依赖关系
  1. 不要传递object,使用useMemo来定义传递的值,防止父组件每次都重新创建该对象
需要注意的是:
Memo的使用使得代码可读性变低,需要考虑很多依赖关系,担心意外情况破坏memoization,开发负担变大,在复杂业务中建议直接选择拆分组件为一个个JSX的方式来实现原本需要memoization化处理的功能,参考https://www.youtube.com/watch?v=lGEMwh32soc
notion image
 
JS记录-旧版React HOC