先一句话总结:
useEffect 在浏览器完成布局和绘制后,异步执行副作用。这意味着,如果你的副作用会改变 DOM 结构或样式,用户可能会看到闪烁。
useLayoutEffect 在浏览器完成布局和绘制前,同步执行副作用。这意味着,如果你的副作用会改变 DOM 结构或样式,用户不会看到闪烁。
详细解释:
在 React 中,有两个 Hooks 可以用来在组件渲染后执行副作用:useEffect 和 useLayoutEffect。它们的用法非常相似,但是它们的执行时机不同。
useEffect 是一个 Hook,它可以让你在函数组件中执行副作用。它的语法如下:
useEffect(() => {
// 在这里执行副作用
}, [dependencies]);useEffect 接受两个参数:一个副作用函数和一个依赖数组。副作用函数会在组件渲染后异步执行。依赖数组中的每一项都会被 React 跟踪,当其中任意一项发生变化时,副作用函数都会重新执行。
下面是一个简单的例子,演示如何使用 useEffect 来更新文档标题:
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}在这个例子中,我们使用 useState Hook 来定义一个状态变量 count 和一个更新状态的函数 setCount。然后,我们使用 useEffect Hook 来定义一个副作用函数,它会在组件渲染后异步执行。在副作用函数中,我们更新文档标题,使其显示当前点击次数。
由于我们将 count 添加到了依赖数组中,所以每当 count 发生变化时,副作用函数都会重新执行,文档标题也会相应更新。
useLayoutEffect 是另一个可以用来执行副作用的 Hook。它的语法和 useEffect 非常相似:
useLayoutEffect(() => {
// 在这里执行副作用
}, [dependencies]);与 useEffect 不同的是,useLayoutEffect 中的副作用函数会在浏览器完成布局和绘制前同步执行。这意味着,如果你的副作用会改变 DOM 结构或样式,用户不会看到闪烁。
下面是一个简单的例子,演示如何使用 useLayoutEffect 来避免闪烁:
import { useState, useLayoutEffect } from 'react';
function Example() {
const [width, setWidth] = useState(0);
useLayoutEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
handleResize();
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<div>
<p>Window width: {width}</p>
</div>
);
}在这个例子中,我们使用 useState Hook 来定义一个状态变量 width 和一个更新状态的函数 setWidth。然后,我们使用 useLayoutEffect Hook 来定义一个副作用函数,它会在浏览器完成布局和绘制前同步执行。在副作用函数中,我们监听窗口大小变化事件,并更新状态变量 width。
由于我们使用了 useLayoutEffect 而不是 useEffect,所以当窗口大小发生变化时,状态变量 width 会立即更新,并且用户不会看到闪烁。
那么,useEffect 和 useLayoutEffect 的区别到底是什么呢?
简单来说,它们的区别就在于执行时机不同。useEffect 在浏览器完成布局和绘制后异步执行副作用;而 useLayoutEffect 在浏览器完成布局和绘制前同步执行副作用。
这意味着,如果你的副作用会改变 DOM 结构或样式,使用 useEffect 可能会导致用户看到闪烁;而使用 useLayoutEffect 则不会。
但是,由于 useLayoutEffect 是同步执行的,所以它可能会阻塞浏览器渲染,导致性能问题。因此,在使用 useLayoutEffect 时应谨慎。
useEffect 和 useLayoutEffect 都是 React Hooks,它们都可以用来在组件渲染后执行副作用。它们的用法非常相似,但是它们的执行时机不同。
通常情况下,你应该使用 useEffect。只有当你的副作用会改变 DOM 结构或样式,并且会导致用户看到闪烁时,才应该使用 useLayoutEffect。但是要注意,由于 useLayoutEffect 是同步执行的,所以它可能会阻塞浏览器渲染,导致性能问题。因此,在使用 useLayoutEffect 时应谨慎。
www.haizhuan.tk