You need to enable JavaScript to run this app. 为什么useMemo没有按预期缓存计算值?
优惠活动
大模型
产品
解决方案
定价
更多

为什么useMemo没有按预期缓存计算值?

问题原因拆解

你提供的示例代码如下:

import { useMemo, useState } from "react";
import "./styles.css";

const calc = (n) => (
  Math.random()
)

export default function App() {
  const [n, setN] = useState(1);
  const r = useMemo(() => 
    calc(n)
  , [n])
  return (
    <div className="App">
      <input onChange={e => setN(e.target.value)}/><br/>
      <strong>useMemo: {r}</strong><br/>
    </div>
  );
}

你观察到的“相同依赖n下,r返回不同结果”的现象,本质是对useMemo的缓存机制存在普遍误解:

useMemo 的真实运行逻辑

  • useMemo从设计定位上就只是临时性能优化工具,React 官方从未承诺它会按照依赖值永久缓存计算结果。
  • 它的基础判断逻辑非常简单:组件每次重新渲染时,对比本次传入的依赖数组和上一次渲染时留存的依赖值,完全相等就临时复用上一次的计算结果;只要有任意依赖值不匹配,就重新执行计算函数生成新值。
  • 为了避免内存泄漏,React 会在合适的时机(比如组件长期闲置、组件卸载后重新挂载)主动清空之前存储的所有memo缓存。这种场景下,哪怕组件重新渲染时的依赖值和历史上完全一致,也会重新执行计算函数,生成全新的结果。

示例代码的具体触发链路

  1. 输入框的onChange事件直接把输入值存入n对应的state,哪怕输入的内容和已有值完全相同,只要触发了state更新流程,就会触发组件重渲染。
  2. 你定义的calc函数接收了参数n但完全没有实际使用,每次执行都会返回一个全新的随机数。一旦遇到依赖不匹配、或是React清缓存的场景,r就会被更新为新的随机值,给人“依赖没变化结果却变了”的观感。

实现稳定缓存的正确方式

useMemo本身做不到“相同入参永久返回固定结果”的需求,这种场景需要搭建独立的缓存存储:

  • 用普通对象维护「入参值 → 计算结果」的映射表,执行计算前先查表,有对应结果就直接返回,没有再执行计算并存入映射表,才能实现可控的稳定缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 07:15:02