认识
一、认识
useMemo
缓存变量数据,当组件重新渲染时不会重新创建变量。(防止父组件重新渲染导致变量数据发生变化)
二、语法
const cachedValue = useMemo(calculateValue, dependencies)
-
calculateValue
: 要缓存计算值的函数。它应该是一个没有任何参数的纯函数,并且可以返回任意类型。React
将会在首次渲染时调用该函数;在之后的渲染中,如果dependencies
没有发生变化,React
将直接返回相同值。否则,将会再次调用calculateValue
并返回最新结果,然后缓存该结果以便下次重复使用。 -
dependencies
: 所有在calculateValue
函数中使用的响应式变量组成的数组。响应式变量包括props
、state
和所有你直接在组件中定义的变量和函数。 -
cachedValue
: 在初次渲染时,useMemo
返回不带参数调用calculateValue
的结果。在接下来的渲染中,如果依赖项没有发生改变,它将返回上次缓存的值;否则将再次调用calculateValue
,并返回最新结果。
三、用法
四、对比
4.1 useMemo 实现原理?
useMemo
用于缓存函数,当组件重现渲染时不会重新创建该函数(防止父组件重新渲染导致函数引用发生变化)
Mount
阶段: 调用 mountMemo
, 创建一个 Hook
对象, 存储在 当前处理的 fiber.memoizedState
中。Hook
对象中也有一个 memoizedState
, 用于存储函数返回值和依赖项。执行函数, 存储返回值和依赖项到 Hook.memoizedState
, 返回结果。
Update
阶段: 从当前的 Fiber
中取出 Hook
链表, 依次循环遍历执行, 执行到 useMemo
链时, 执行 updateMemo
, 通过 Object.is
循环对比依赖项数组, 如果依赖项中的每一项依赖都没有发生变化, 则不做任何处理。如果发生变化, 重新执行函数, 重新存储返回值和依赖项到 Hook.memoizedState
, 返回结果。
4.2 useCallback 和 useMemo 有什么区别?
useMemo
缓存传入函数执行的返回值, 根据依赖项重新计算结果, 类似于 Vue
中的 Computed
。而 useCallback
缓存传入的函数, 防止父组件重新渲染导致函数引用发生变化。
4.3 如何基于 useMemo 实现 useCallback?
function useCallback(callback, deps) {
return useMemo(() => callback, deps);
}