You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何useMemo钩子无法在该场景下避免不必要的计算?

useMemo 失效问题分析与解决

先拆解两种场景的核心原因:

场景1:items 声明在组件外部

你误以为第一次点击会耗时,是混淆了执行时机——items 是组件加载前就创建好的全局常量,组件首次挂载时,useMemo 就会执行一次 items.find(),这个过程在组件渲染阶段完成,而非点击按钮时。后续点击修改 count 触发组件重渲染时,items 的引用从未改变,useMemo 直接返回缓存结果,自然不会有耗时操作,点击也就流畅。

场景2:items 声明在组件内部

每次组件重渲染(比如点击按钮改变 count),都会重新创建整个 items 数组,新数组的引用和旧数组完全不同。useMemo 的依赖数组 [items] 检测到引用变化,就会重复执行 find() 操作,连续点击等于重复跑大量计算,必然卡顿。

正确处理方式

情况1:静态数据(不依赖组件内部状态/Props)

维持当前把 items 放在组件外部的写法即可,这是最优解——useMemo 仅在组件首次挂载时执行一次,后续完全复用缓存结果。

情况2:动态数据(依赖组件内部状态/Props)

如果 items 必须在组件内生成(比如要根据 Props 动态调整),要用 useMemo 包裹 items 的创建,保证其引用稳定:

import { useMemo, useState } from "react";

export default function UseMemoExample() {
  const [count, setCount] = useState(0);

  // 用 useMemo 包裹 items 创建,依赖为空则仅生成一次
  const items = useMemo(() => {
    return new Array(1_999_999).fill(0).map((_, i) => {
      return {
        id: i,
        isSelected: i === 1_999_998,
      };
    });
  }, []); // 若依赖Props/其他状态,需添加到依赖数组中

  const selectedItem = useMemo(() => {
    return items.find((item) => item.isSelected);
  }, [items]);  

  return (
    <div className="container">
      <h2>useMemo</h2>
      <p>Count is {count}</p>
      <p>Selected Item is {selectedItem?.id}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

这样 items 的引用只会在依赖变化时更新,selectedItem 的 useMemo 也仅在 items 真的变化时重新计算,避免了不必要的重复执行。

内容的提问来源于stack exchange,提问作者kylehink97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:15:15