MST

星途 面试题库

面试题:React 中 useLayoutEffect 与 useEffect 在触发时机上有何不同

请详细阐述 React 中 useLayoutEffect 和 useEffect 钩子函数在触发时机方面的区别,并举例说明在什么场景下这种触发时机的差异会影响到页面的呈现效果。
46.6万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

触发时机区别

  1. useEffect:在浏览器完成布局与绘制后,异步触发执行。它不会阻塞浏览器渲染,所以不会影响用户体验。例如在页面已经渲染完成后进行一些数据获取、副作用操作等。
  2. 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>
    );
};
  1. 使用 useEffect
    • 页面先渲染出一个空的 <div>,因为 useEffect 是异步执行的,在页面渲染完成后才获取 div 的宽度并更新文本。这可能会导致用户先看到一个没有文本的 div,然后文本才出现,产生闪烁效果。
  2. 使用 useLayoutEffect
    • 由于 useLayoutEffect 是同步执行的,在浏览器渲染前就获取了 div 的宽度并更新了文本。所以用户看到的是一开始就带有正确文本的 div,不会出现闪烁现象。在对页面视觉一致性要求较高的场景,如动画、测量布局后立即更新样式等,useLayoutEffect 能确保页面呈现更流畅和一致。