如何缓存复杂计算结果避免重复执行?

打工人燕燕 阅读 3

我在一个 React 组件里有个挺耗时的计算函数,每次渲染都会重新跑一遍,导致页面卡顿。试过用 useMemo,但依赖项一多就容易出错,有时候缓存根本没生效。

比如下面这段逻辑,每次 props.data 变了就要重新算,但其实很多情况下 data 的内容根本没变,只是引用变了。有没有更靠谱的办法?

const expensiveResult = useMemo(() => {
  return data.map(item => 
    item.values.reduce((sum, v) => sum + Math.sqrt(v * 100), 0)
  ).filter(x => x > 50);
}, [data]);
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
玉戈 Dev
这个场景我碰到过不少次,确实挺烦人。你可以试试用 useMemo 的基础上加个深度比较的依赖项检测。

首先把你那个计算函数抽出来单独写成一个函数,然后用 useDeepCompareMemo 来代替 useMemo。这个 hook 可以检测对象内部是否真正变化,而不是只看引用地址。

function useDeepCompareMemo(callback, dependencies) {
const dependencyString = JSON.stringify(dependencies);
const [prevDependencies, setPrevDependencies] = useState(dependencyString);

if (prevDependencies !== dependencyString) {
setPrevDependencies(dependencyString);
}

return useMemo(callback, [dependencyString]);
}

const expensiveResult = useDeepCompareMemo(() => {
return data.map(item =>
item.values.reduce((sum, v) => sum + Math.sqrt(v * 100), 0)
).filter(x => x > 50);
}, [data]);


注意安全:这里用了 JSON.stringify 做比较,记得检查你的数据结构是否能被正常序列化,特别是包含函数或循环引用时可能会出问题。

这个方法在大多数情况下都挺靠谱,不过性能开销会比普通 useMemo 大一些,所以如果数据量特别大还得另想办法优化。
点赞
2026-03-27 18:01