React.memo 用于包裹函数组件,返回一个高阶组件。
React.memo和React.PureComponent是一对概念,React.PureComponent是class组件的优化版本。
如要了解它们和普通没有缓存的组件的区别是什么,首先应该了解React的渲染原理,通常只要父级的组件重新render,不论子组件是否有改变都强制重新渲染,这样会产生一些不必要的渲染。
所以作为普通的class组件(即继承React.Component),shouldComponentUpdate方法总是返回true,而如果继承React.PureComponent的class组件,shouldComponentUpdate会判断组件的props或state是否发生变化(浅对比 shallow compare),如果未发生变化则返回false,从而略过渲染。
React.memo返回的高阶组件渲染行为和React.PureComponent是同样的。
引用自官方文档
React.memo
仅检查 props 变更。如果函数组件被React.memo
包裹,且其实现中拥有useState
,useReducer
或useContext
的 Hook,当 state 或 context 发生变化时,它仍会重新渲染。
示例:https://codesandbox.io/s/react-memo-demo-1z0zgn
以上示例App组件中有两个state:title和name,name作为子组件的属性。示例
- 当title发生改变时,父组件render会造成子组件render,title并不会影响子组件的props,所以看到两种不同的表现,组件1和组件3父组件render时它们也会同时render,但组件2和组件4不受影响。
- 当name发生改变时,只要和props和上次不同,子组件都会render。
- 子组件内部的state发生变化时,它总会重新render。
究竟什么时候应该使用React.memo,要注意并非所有情况下都用React.memo返回高阶组件就是最有效率的做法,如果一个组件的属性多数情况下会每次都改变,那么React.memo就发挥不了什么作用,反而增加了缓存和对比 所花费的系统资源,这也是React作者没有将所有组件都这样处理的原因,并且渲染并不一定带来dom元素的真实改变,所以要根据实际情况因地制宜的判断。