useMemo与解构语法结合的工作原理及代码合理性解析
代码解析与问题解答
这段代码的作用
你写的这段代码,核心是想用useMemo把searchHelp对象缓存起来,再从中解构出五个变量。useMemo的逻辑是:只有当依赖项searchHelp的引用发生变化时,才会返回新的对象;如果searchHelp没变化,就复用之前缓存的对象,避免组件每次渲染都生成新对象。
但要注意:这段代码没法直接让解构出来的单个变量被缓存——解构只是从对象里读取属性的操作,useMemo只维护了整个对象的引用稳定性,单个变量的稳定性还是取决于searchHelp自身的属性是否变化,以及searchHelp本身是不是稳定的。
解构语法与useMemo的配合效果
- 直接解构
useMemo返回的对象,单个变量不会自动被memoized:useMemo只负责缓存整个对象的引用,不管对象内部的属性。每次组件渲染时,解构都是重新读取属性值,属性值稳不稳定,本质还是看原对象的属性状态。 - 要实现单个变量的memoized,有两种可行方式:
- 在
useMemo内部单独处理每个变量,再解构:
这种方式能让每个变量基于自身的依赖被缓存,但依赖项的编写会比较繁琐。const { searchSupported, searchPaginationQuery, searchModalTableColumns, textFieldAccessor, searchSourceContext } = useMemo(() => ({ searchSupported: searchHelp.searchSupported, searchPaginationQuery: searchHelp.searchPaginationQuery, searchModalTableColumns: searchHelp.searchModalTableColumns, textFieldAccessor: searchHelp.textFieldAccessor, searchSourceContext: searchHelp.searchSourceContext }), [searchHelp.searchSupported, searchHelp.searchPaginationQuery, searchHelp.searchModalTableColumns, searchHelp.textFieldAccessor, searchHelp.searchSourceContext]); - 如果
searchHelp本身已经是被缓存过的稳定对象,直接解构即可,没必要额外套useMemo;如果searchHelp每次渲染都会新建,那先缓存searchHelp再解构,但此时解构变量的稳定性还是和searchHelp的属性一致。
- 在
你期望的“五个变量都被memoized”的效果,当前这段代码无法实现,因为它只缓存了整个searchHelp对象,单个变量并没有被单独缓存。只要searchHelp里任意一个属性发生变化,整个useMemo返回的对象就会更新,所有解构出来的变量都会读取新值。
内容的提问来源于stack exchange,提问作者Konstantin Karpov
相关产品推荐
相关产品推荐

