作为「性能优化」手段,一般用useMemo缓存函数组件中比较消耗性能的计算结果:
成都创新互联公司,为您提供成都网站建设、成都网站制作、网站营销推广、网站开发设计,对服务成都主动防护网等多个行业拥有丰富的网站建设及推广经验。成都创新互联公司网站建设公司成立于2013年,提供专业网站制作报价服务,我们深知市场的竞争激烈,认真对待每位客户,为客户提供赏心悦目的作品。 与客户共同发展进步,是我们永远的责任!
- function App() {
- const memoizedValue = useMemo(
- () => computeExpensiveValue(a, b),
- [a, b]
- );
- // ...
- }
只有在依赖项改变后才会重新计算新的memoizedValue。
你有没有想过,如果用useMemo缓存函数组件的返回值,会怎么样呢?
举个例子
我们有个全局context —— AppContext。
由于同学们偷懒,随着项目的迭代,新增的context都选择放在AppContext里,导致AppContext包含的内容越来越多。
现在我们有个Tree组件,他会渲染一个很耗性能的大组件ExpensiveTree。
- function Tree() {
- let appContextValue = useContext(AppContext);
- let theme = appContextValue.theme;
- return
; - }
该组件内部依赖AppContext中的theme状态。
由于AppContext中包含很多与theme无关的state,导致每次其他无关的state更新,Tree都会重新render,进而ExpensiveTree组件也重新render。
现在这个优化任务交到了你手上,该怎么办呢?
优化ExpensiveTree
这时候,useMemo就能派上用场:
- function Tree() {
- let appContextValue = useContext(AppContext);
- let theme = appContextValue.theme;
- return useMemo(() => {
- return
; - }, [theme])
- }
我们将返回的ExpensiveTree作为useMemo返回值,theme作为依赖。
这样,即使AppContext改变导致Tree反复render,ExpensiveTree也只会在theme改变后render。
[[380080]]
原理解析
要理解这么做有效的原因,需要了解三点:
回答第一个问题:useMemo会将第一个参数(函数)的返回值保存在组件对应fiber中,只有在依赖项(第二个参数)变化后才会重新调用第一个参数(函数)计算一个新值。
回答第二个问题:函数组件的返回值是JSX对象。
同一个函数组件调用多次,返回的是多个「不同」的JSX对象(即使props未变,但JSX是新的引用)。
按照以上两个回答,我们可以得出结论:
第三个问题,函数组件需要同时满足如下条件才不会render:
1 oldProps === newProps
前后两次更新props全等,注意是「全等」。
2 组件context没有变化
3 workInProgress.type === current.type
组件更新前后fiber.type未变化,比如div没有变为p。
4 !includesSomeLane(renderLanes, updateLanes)
当前fiber上不存在更新,或者存在更新但优先级低。
当我们不使用useMemo包裹返回值,每次Tree render返回的都是全新的JSX对象。
所以对于ExpensiveTree,oldProps !== newProps。
再看2:ExpensiveTree内部context没变,满足
再看3:ExpensiveTree更新前后type都是ExpensiveTree,满足
再看4: ExpensiveTree内没有状态更新,满足
所以,当我们使用useMemo包裹ExpensiveTree后,当theme不变,每次Treerender后返回的都是同一个JSX对象,满足第一条。
基于这个原因,ExpensiveTree不会render。
总结
这篇文章提到的useMemo用法,并未在官网文档中体现,而是在#15156[1]中由Dan介绍。
相比Vue,React更灵活,开发过程中需要开发者注意更多细节。要完全了解React,可能需要学习一些源码层面的知识。
参考资料
[1]#15156:
https://github.com/facebook/react/issues/15156#issuecomment-474590693
分享文章:奇怪的useMemo知识增加了
文章地址:http://www.mswzjz.cn/qtweb/news29/489179.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能