跳到主要内容

认识

2023年02月22日
柏拉文
越努力,越幸运

一、认识


useMemo 缓存变量数据,当组件重新渲染时不会重新创建变量。(防止父组件重新渲染导致变量数据发生变化)

二、语法


const cachedValue = useMemo(calculateValue, dependencies)
  • calculateValue: 要缓存计算值的函数。它应该是一个没有任何参数的纯函数,并且可以返回任意类型。React 将会在首次渲染时调用该函数;在之后的渲染中,如果 dependencies 没有发生变化,React 将直接返回相同值。否则,将会再次调用 calculateValue 并返回最新结果,然后缓存该结果以便下次重复使用。

  • dependencies: 所有在 calculateValue 函数中使用的响应式变量组成的数组。响应式变量包括 propsstate 和所有你直接在组件中定义的变量和函数。

  • 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);
}