useLayoutEffect(setup, dependencies?)
useLayoutEffect(() => {
const height = ref.current?.getBoundingClientRect().height ?? 0;
setHeight(height); // 描画前に確定させる
}, []);import { useRef, useLayoutEffect, useState } from 'react';
// ── useEffect vs useLayoutEffect ─────────────────────
// useEffect: 画面描画「後」に非同期で実行
// useLayoutEffect: 画面描画「前」に同期で実行(DOM測定に使う)
// ── 典型的な用途: 要素サイズの測定 ──────────────────
function Tooltip({ text }: { text: string }) {
const ref = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(0);
// ✅ DOMが描画される直前にサイズを取得
// → useEffect だとチラつきが起きる場合がある
useLayoutEffect(() => {
if (ref.current) {
const rect = ref.current.getBoundingClientRect();
setWidth(rect.width); // 実際の描画幅を取得
}
}, [text]); // text が変わるたびに再計測
return (
<div ref={ref} style={{ position: 'relative' }}>
{text}
<span style={{ width }}> ← 幅: {width}px</span>
</div>
);
}
// ── ⚠️ 注意 ─────────────────────────────────────────
// useLayoutEffect はサーバーサイドレンダリング(SSR)では
// 実行されない → Next.js で使う場合は注意が必要SSRではuseLayoutEffectは実行されず警告が出る。SSRとCSRの両方で動かしたい場合はuseEffectを使うか、useIsomorphicLayoutEffectパターンを使う。