React缓存,探讨memo函数如何缓存阻止(子)组件渲染?
发布于 作者:苏南大叔 来源:程序如此灵动~

React
里面比较高阶的使用方式:memo()
函数是本文的主要内容。memo
和useMemo()
看起来很相似,使用上却有很大的区别。useMemo()
作用在函数之上,是对昂贵运算逻辑函数结果的缓存,只能在函数式组件里面使用。memo
作用在组件之上,是对组件的缓存,函数式组件类组件,都是其作用对象。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0
,create-react-app@5.0.1
,react-router-dom@6.27.0
,react@18.3.1
。
memo高阶函数
memo()
直接套用在组件上,无关组件的写法是函数式写法,还是类写法,都可以使用memo()
高阶函数。它对组件为目标进行缓存,根据props
决定是否执行渲染。主打的就是(子)组件无渲染无变化。
- 默认情况下,如果传入组件的所有属性,都保持一致。那么,这个组件就没有渲染的必要性。
- 当然,也可以自定义函数来对前后的属性进行对比。来自行决定是否渲染。
return false
渲染,true
不渲染。 - 其中特殊的地方就是传入属性是函数定义的时候,表面上是同样的函数,但是如果内存地址不一样的话。也是会被判定为非相同的值的。会被执行渲染。【待续】
测试代码
在下面的测试代码中,一共有五个子组件Child
被加载。其中四个被memo
高阶函数所包裹。每个子组件里面都输出了数字时间戳,父组件刷新的时候,如果这些数字时间戳没有变化,那么就证明对应的子组件被缓存了,并没有发生再次渲染。

表格总结
父组件重新渲染的时候,子组件也会即将触发渲染。但是,memo
高阶函数,给其包裹的子组件一次选择的机会。如果变化前后的各个属性props
没有发生变化,则拒绝渲染。当然,这个规则也可以自定义,根据需要来决定是否渲染。其中,有个容易踩坑的地方,就是如果传入props
的属性是个函数的时候,这个函数可能是每次都重新生成的。这个时候,子组件会被渲染。
序号 | 子组件 | 是否Memo | props属性 | 是否渲染 |
---|---|---|---|---|
1 | <Child /> | 否 | 无 | 恒定渲染 |
2 | <MemoChild fn={fn} /> | 是 | fn是个变化的函数 | 恒定渲染 |
3 | <MemoChild2 point={p} /> | 是 | point是个变化的数字 | 有条件渲染 |
4 | <MemoChild /> | 是 | 无任何属性 | 恒定不渲染 |
5 | <MemoChild fn={fn2} /> | 是 | fn不变是个useState导出 | 恒定不渲染 |
相关文章
memo
函数的相关文章:


