用通俗的语言说明React的 useMemo、useCallback、useEffect 和 useLayoutEffect 的区别
2023-10-12 11:15:06
事件-状态模型:理解 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]);
依赖数组
依赖数组 是 useMemo
、useCallback
和 useEffect
函数中最重要的参数之一。依赖数组指定了函数何时应该重新执行。
当依赖数组发生变化时,函数就会重新执行。否则,函数就会返回上次计算的值或回调函数。
总结
现在我们已经对 useMemo
、useCallback
、useEffect
和 useLayoutEffect
函数有了基本的了解。以下是它们的异同:
useMemo
和useCallback
函数允许你在函数组件中使用缓存和回调函数。useEffect
和useLayoutEffect
函数允许你在函数组件中执行副作用。useLayoutEffect
函数会在浏览器完成布局和绘制之后执行。- 依赖数组指定了函数何时应该重新执行。
常见问题解答
-
为什么使用 Hooks?
Hooks 允许你在函数组件中使用状态和副作用,而无需使用类组件。这使代码更简洁、易于维护。 -
什么时候使用
useMemo
?
当需要对昂贵的计算进行缓存时,使用useMemo
。它可以防止在不必要的情况下重新执行计算。 -
什么时候使用
useCallback
?
当需要在多个地方使用回调函数时,使用useCallback
。它可以防止每次渲染组件时都创建新的回调函数。 -
什么时候使用
useEffect
?
当需要在组件挂载、更新或卸载时执行副作用时,使用useEffect
。副作用可能包括网络请求、DOM 操作或订阅事件。 -
什么时候使用
useLayoutEffect
?
当需要在浏览器完成布局和绘制之后执行副作用时,使用useLayoutEffect
。这对于在组件渲染后更新 DOM 元素的位置或尺寸非常有用。