useLayoutEffect 在真实 DOM 存在后、显示前执行useLayoutEffect 执行时DOM 已经创建完成但浏览器还没开始绘制屏幕。所以✅能拿到ref.currentDOM 节点已经存在✅能读取 DOM 尺寸offsetHeight、clientWidth 等✅能同步修改 state❌屏幕还没渲染画面所以不会闪屏2. 执行顺序非常关键你的组件运行流程是这样的React构建虚拟 DOMReact 构建真实 DOM此时 div 已经存在执行 useLayoutEffect这里能拿到divRef.current能读取高度能同步更新minHeightReact 用新 state 更新 DOM浏览器才开始绘制屏幕读取一个 DOM 节点的高度同步设置另一个元素的高度这正是useLayoutEffect 最经典的使用场景读取 DOM 布局 → 同步更新样式避免闪烁。对比 useEffect你就能看出区别如果换成useEffectDOM 已创建浏览器已经绘制了画面再执行 useEffect再改高度 →会看到页面闪一下而useLayoutEffect是绘制前执行改完样式再统一绘制无闪烁、更流畅1. 操作DOM元素布局- 可以在 useLayoutEffect 中获取DOM元素的尺寸并进行相关布局调整。- 示例创建一个组件该组件中有一个 div 元素当组件挂载后获取这个 div 的高度并将这个高度值作为另一个 div 的最小高度。import React, { useRef, useLayoutEffect, useState } from react; function LayoutComponent() { const divRef useRef(null); const [minHeight, setMinHeight] useState(); useLayoutEffect(() { if (divRef.current) { const height divRef.current.offsetHeight; setMinHeight(${height}px); } }, []); return ( div div ref{divRef} This is a div to measure height. /div div style{{ minHeight }} This divs min - height is set based on the above divs height. /div /div ); }2. 实现复杂的UI同步更新- 例如在一个列表组件中当新的数据加载进来时需要同步更新列表项的位置和布局。假设列表项有动画效果并且动画的起始位置需要和数据加载后的实际位置一致。import React, { useState, useLayoutEffect, useEffect } from react; import ./styles.css; function AnimatedList() { const [listData, setListData] useState([]); useEffect(() { // 模拟异步获取数据 setTimeout(() { setListData([1, 2, 3, 4, 5]); }, 1000); }, []); const listItemsRef useRef([]); useLayoutEffect(() { listItemsRef.current.forEach((itemRef, index) { if (itemRef.current) { // 可以在这里进行一些同步的布局调整比如设置动画的起始位置 const top index * 50; itemRef.current.style.top ${top}px; } }); }, [listData]); return ( ul classNamelist {listData.map((data, index) ( li ref{el listItemsRef.current[index] el} key{index} {data} /li ))} /ul ); }3. 和第三方UI库的同步交互- 有些UI库在初始化或更新组件时需要在DOM更新后立即进行操作。比如一个模态框库需要在模态框的DOM元素渲染完成后立即设置其位置和显示属性。import React, { useRef, useLayoutEffect } from react; import Modal from some - modal - library; function CustomModal() { const modalRef useRef(null); useLayoutEffect(() { if (modalRef.current) { const modal new Modal(modalRef.current); // 初始化模态框比如设置位置、大小等属性 modal.setPosition(center); modal.setSize(medium); modal.show(); } }, []); return ( div ref{modalRef} pModal content here/p /div ); }