反应:useEffect vs useMemo vs useState

React: useEffect vs useMemo vs useState

我试图在网上找到一个简明的答案,但运气不好。

关于 useEffectuseMemouseState 之间的区别,下列说法正确吗?

还有其他我遗漏的主要区别吗?

你的观点基本正确,一些小的说明:

useState 导致 re-render 调用 setState 方法(数组中的第二个元素 returned)。它没有像 useMemo 或 useEffect 这样的依赖项。

useMemo 仅在其依赖数组中的元素发生变化时才重新计算一个值(如果没有依赖关系 - 即数组为空,它只会重新计算一次)。如果数组被遗漏,它将在每次渲染时重新计算。调用该函数不会导致 re-render。此外,它 运行s 组件渲染期间而不是之前。

useEffect 在每次渲染 之后 调用,如果其依赖数组中的元素已更改或数组被遗漏。如果数组为空,它只会在初始挂载时 运行 一次(如果你 return 一个清理函数则卸载)。

您可以随时查看 Hooks API Reference,我认为这是一份非常可靠的文档

  • useEffect(callback, [dependency])的return值为void,在render()之后执行。
  • useMemo(callback, [dependency]) 的 return 值不是 void 而是记忆值,它在 render().
  • 期间执行

useEffect() 可以在以下情况下提供与 useMemo() 相同的优化:

  • 在昂贵的计算中使用的状态变量(即 count1)是 useEffect 的唯一依赖项。
  • 当我们不介意将昂贵的计算值存储在状态变量中时。
const [count1, setCount1] = useState(0);
const [expensiveValue, setExpensiveValue] = useState(null);
useEffect(() => {
    console.log("I am performing expensive computation");
    setExpensiveValue(((count1 * 1000) % 12.4) * 51000 - 4000);
  }, [count1]);   
  • 唯一的区别是,useEffect() 使昂贵的计算值在 render() 之后可用,而 useMemo() 使该值在 render() 期间可用。
  • 大多数时候这无关紧要,因为如果该值已计算用于在 UI、useEffect()useMemo() 中呈现,两者都会在浏览器完成之前使该值可用画.

useMemo 用于记忆属于组件但不一定属于组件状态的 calculations/values 例如依赖组件的验证、方法必须 return 一个值;

  const validEmail = React.useMemo(() => validateEmail(email), [email])
  /* Now use 'validEmail' variable across the component, 
     whereas 'useEffect' return value is void and only used for unmounting duties, 
     like unsubscribing from subscription e.g. removeInterval*/

from docs:

Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.


useEffect Side effects:

Mutations, subscriptions, timers, logging, and other side effects

setStatesetTimeout's setInterval' ref 赋值,API 调用,或任何不执行繁重计算的东西都属于这里。

还要记住,优化是有代价的,因此 React 建议仅在需要 memoization/optimisation 时使用 useMemo,而在其他情况下,在必要时依赖 useEffect

You may rely on useMemo as a performance optimization, not as a semantic guarantee.

In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.


[state, setState] = useState() that is 更新给定的状态变量,该变量在重新渲染期间保持稳定并调用附加到它的 setState 触发重新渲染。这个钩子的目的与上面两个钩子没有太大关系。