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
相关产品推荐
相关产品推荐

