React useLayoutEffect
React 中在浏览器绘制前同步执行的副作用 Hook 及其与 useEffect 的边界。
#tech / dev / frame
#resource / react
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: React MOC
- 上位主题: react-hooks, react-use-effect
- 相关概念: React组件渲染与重渲染
React useLayoutEffect
useLayoutEffect 和 useEffect 一样都属于副作用 Hook,但它执行得更早:在浏览器完成绘制前同步执行。
一句话定义
如果你的副作用必须在用户看到页面前就完成,避免布局闪动或读写错位,才考虑 useLayoutEffect。
最小例子
function Tooltip() {
const boxRef = useRef<HTMLDivElement | null>(null)
const [height, setHeight] = useState(0)
useLayoutEffect(() => {
const nextHeight = boxRef.current?.getBoundingClientRect().height ?? 0
setHeight(nextHeight)
}, [])
return <div ref={boxRef}>高度: {height}</div>
}
如果你需要在绘制前先读取布局并立刻修正界面,useLayoutEffect 更合适。
最常见的场景
- 读取元素尺寸
- 同步修改布局相关 DOM
- 避免界面先闪一下再修正
为什么不能默认都用它
因为它会阻塞浏览器绘制,成本比 useEffect 更高。大多数普通副作用仍然应该优先用 useEffect。
和 useEffect 的边界
useEffect:更适合一般副作用同步useLayoutEffect:更适合必须在绘制前完成的布局相关副作用
什么时候不要滥用
因为它会阻塞浏览器绘制,所以不要把普通请求、订阅、日志、非视觉同步任务都写到这里。
如果不是明确的布局时机问题,优先还是 useEffect。
最短记忆方式
useLayoutEffect 解决的是“不能让用户先看到错误布局”的问题,不是 useEffect 的更高级版本。