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

useMemo依赖项行为疑问:对象状态为何未触发重计算?

为什么依赖对象类型状态的useMemo没有在每次渲染时重新计算?

首先明确核心逻辑:useMemo通过Object.is()判断依赖是否变化,只有当依赖的引用或值发生改变时,才会重新执行回调函数。

两种对象的本质区别

  • useState保存的对象状态a:
    用useState初始化的对象,其引用只会在你调用setA传入新的对象引用时才会改变。比如点击第二个按钮更新aa时,组件虽然重新渲染,但a的引用和上一次渲染完全一致,Object.is()对比前后两次的a结果为true,所以依赖[a]的useMemo不会重新计算,也就不会打印obj。

  • 组件内普通对象temp:
    temp是在组件每次渲染时都会重新创建的新对象,每次渲染它的引用都是全新的。Object.is()对比前后两次的temp结果为false,所以依赖[temp]的useMemo每次都会重新执行,打印obj2。

验证场景

当你点击第一个按钮时,调用setA(prev => ({a: prev.a +1})),这里返回了一个新的对象,a的引用发生了变化,此时useMemo的依赖[a]判定为变化,就会重新计算obj并打印obj。

示例代码

import { useMemo, useState } from "react";

export default function App() {
  const temp = { a: 1 };
  const [a, setA] = useState({ a: 1 });
  const [aa, setAA] = useState(1);

  const obj = useMemo(() => {
    console.log("obj");
    return { b: a.a };
  }, [a]);

  const obj2 = useMemo(() => {
    console.log("obj2");
    return { b: temp.a };
  }, [temp]);

  return (
    <div className="App">
      <button onClick={() => setA((prev) => ({ a: prev.a + 1 }))}>
        button {a.a}
      </button>
      <div>{obj.b}</div>
      <div>{obj2.b}</div>
      <button onClick={() => setAA((prev) => prev + 1)}>premitive {aa}</button>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:42:53