小能豆

useMemo 与 useEffect + useState 对比

javascript

使用 (例如对于密集函数调用) 而不是使用和useMemo的组合有什么好处吗?useEffect``useState

这里有两个自定义钩子,乍一看,它们的工作原理完全相同,除了useMemo的返回值是null在第一次渲染时:

查看 CodeSandbox

useEffect 和 useState

import { expensiveCalculation } from "foo";

function useCalculate(someNumber: number): number | null {
  const [result, setResult] = useState<number | null>(null);

  useEffect(() => {
    setResult(expensiveCalculation(someNumber));
  }, [someNumber]);

  return result;
}

使用备忘录

import { expensiveCalculation } from "foo";

function useCalculateWithMemo(someNumber: number): number {
    return useMemo(() => {
        return expensiveCalculation(someNumber);
    }, [someNumber]);
};

每次参数发生变化时,两者都会计算结果,启动时someNumber的记忆useMemo在哪里?


阅读 42

收藏
2024-06-03

共1个答案

小能豆

每次更改useEffect都会setState引发额外的渲染:第一次渲染会因为陈旧数据而“落后”,然后它会立即使用新数据排队进行额外的渲染。


假设我们有:

// Maybe I'm running this on a literal potato
function expensiveCalculation(x) { return x + 1; };

假设x最初为 0:

  • useMemo版本立即呈现1
  • 版本useEffect渲染null,然后在组件渲染效果运行后,更改状态,并使用排队新的渲染1

那么如果我们改为x2:

  • 运行useMemo3渲染。
  • 版本useEffect运行,并再次渲染1,然后效果触发并且组件使用正确的值重新运行3

就运行频率而言expensiveCalculation,两者的行为相同,但该useEffect版本导致两倍的渲染,这会因其他原因而对性能产生不利影响。

另外,在我看来,这个useMemo版本更简洁,更易读。它不会引入不必要的可变状态,移动部件也更少。

因此您最好只使用useMemo这里。

2024-06-03