返回

用通俗的语言说明React的 useMemo、useCallback、useEffect 和 useLayoutEffect 的区别

前端

事件-状态模型:理解 React Hooks 的基础

在深入探讨 React Hooks 之前,了解一个通用的模型至关重要。这个模型将帮助我们理解 Hooks 的含义和用法。

事件-状态模型

任何逻辑都可以分解为如下模型:事件引起状态的变化,状态的变化又发起新的事件 。事件在前,状态在后。

让我们以一个简单的例子来说明这个模型:

const [count, setCount] = useState(0);

const handleClick = () => {
  setCount(count + 1);
};

在这个例子中,点击按钮(事件)会触发 setCount 函数(状态),将 count 的值增加 1。

React Hooks

React Hooks 是 React 16.8 中引入的一组函数,它们允许你在函数组件中访问状态和执行副作用。下面是一些最常用的 Hooks:

useMemo

useMemo 函数让你可以在函数组件中使用缓存。当 useMemo 的依赖数组发生变化时,它会重新执行函数并返回新的值。否则,它会返回上次计算的值。

const memoizedValue = useMemo(() => {
  // 这是一个计算密集型的函数
  return computeExpensiveValue();
}, [dependencyArray]);

useCallback

useCallback 函数让你可以在函数组件中使用回调函数。当 useCallback 的依赖数组发生变化时,它会返回一个新的回调函数。否则,它会返回上次返回的回调函数。

const memoizedCallback = useCallback(() => {
  // 这是一个需要在多个地方使用的回调函数
  doSomething();
}, [dependencyArray]);

useEffect

useEffect 函数让你可以在函数组件中执行副作用。当 useEffect 的依赖数组发生变化时,它会在组件挂载、更新和卸载时执行指定的函数。

useEffect(() => {
  // 这是一个副作用函数
  doSomething();

  // 返回一个清理函数
  return () => {
    // 在组件卸载时执行的清理工作
    cleanup();
  };
}, [dependencyArray]);

useLayoutEffect

useLayoutEffect 函数与 useEffect 函数非常相似,但它会在浏览器完成布局和绘制之后执行。

useLayoutEffect(() => {
  // 这是一个副作用函数
  doSomething();

  // 返回一个清理函数
  return () => {
    // 在组件卸载时执行的清理工作
    cleanup();
  };
}, [dependencyArray]);

依赖数组

依赖数组useMemouseCallbackuseEffect 函数中最重要的参数之一。依赖数组指定了函数何时应该重新执行。

当依赖数组发生变化时,函数就会重新执行。否则,函数就会返回上次计算的值或回调函数。

总结

现在我们已经对 useMemouseCallbackuseEffectuseLayoutEffect 函数有了基本的了解。以下是它们的异同:

  • useMemouseCallback 函数允许你在函数组件中使用缓存和回调函数。
  • useEffectuseLayoutEffect 函数允许你在函数组件中执行副作用。
  • useLayoutEffect 函数会在浏览器完成布局和绘制之后执行。
  • 依赖数组指定了函数何时应该重新执行。

常见问题解答

  1. 为什么使用 Hooks?
    Hooks 允许你在函数组件中使用状态和副作用,而无需使用类组件。这使代码更简洁、易于维护。

  2. 什么时候使用 useMemo
    当需要对昂贵的计算进行缓存时,使用 useMemo。它可以防止在不必要的情况下重新执行计算。

  3. 什么时候使用 useCallback
    当需要在多个地方使用回调函数时,使用 useCallback。它可以防止每次渲染组件时都创建新的回调函数。

  4. 什么时候使用 useEffect
    当需要在组件挂载、更新或卸载时执行副作用时,使用 useEffect。副作用可能包括网络请求、DOM 操作或订阅事件。

  5. 什么时候使用 useLayoutEffect
    当需要在浏览器完成布局和绘制之后执行副作用时,使用 useLayoutEffect。这对于在组件渲染后更新 DOM 元素的位置或尺寸非常有用。