面试题答案
一键面试触发时机区别
- useEffect:在浏览器完成布局与绘制后,异步触发执行。它不会阻塞浏览器渲染,所以不会影响用户体验。例如在页面已经渲染完成后进行一些数据获取、副作用操作等。
- useLayoutEffect:在浏览器完成布局与绘制前,同步触发执行。这意味着它会阻塞浏览器渲染,直到其执行完毕。类似于 componentDidMount 和 componentDidUpdate 中立即执行的操作。
场景举例及影响
假设在一个 React 组件中有一个元素,需要根据其宽度动态调整文本内容。
import React, { useEffect, useLayoutEffect, useState } from'react';
const ExampleComponent = () => {
const [text, setText] = useState('');
const divRef = React.createRef();
// 使用 useEffect
useEffect(() => {
if (divRef.current) {
const width = divRef.current.offsetWidth;
setText(`宽度是: ${width}`);
}
}, []);
// 使用 useLayoutEffect
useLayoutEffect(() => {
if (divRef.current) {
const width = divRef.current.offsetWidth;
setText(`宽度是: ${width}`);
}
}, []);
return (
<div ref={divRef}>
{text}
</div>
);
};
- 使用 useEffect:
- 页面先渲染出一个空的
<div>
,因为 useEffect 是异步执行的,在页面渲染完成后才获取 div 的宽度并更新文本。这可能会导致用户先看到一个没有文本的 div,然后文本才出现,产生闪烁效果。
- 页面先渲染出一个空的
- 使用 useLayoutEffect:
- 由于 useLayoutEffect 是同步执行的,在浏览器渲染前就获取了 div 的宽度并更新了文本。所以用户看到的是一开始就带有正确文本的 div,不会出现闪烁现象。在对页面视觉一致性要求较高的场景,如动画、测量布局后立即更新样式等,useLayoutEffect 能确保页面呈现更流畅和一致。