はじめに
DOM要素のサイズが変更されたことを検知して、そのサイズにあったコンポーネントの表示に変更したいといったことがあるかと思います。
ReactではuseRefを使用することでDOM要素にアクセスすることが可能ですが、変更があってもコンポーネントが再レンダリングされないためDOM要素のサイズ変更を検知することができません。
そういった場合には、ResizeObserverというWebAPIを使うことで実現することができます。
サンプルコード
以下、サンプルコードになります。右端を選択してドラッグするとプレビューで動作を確認できます。
(プレビューをデフォルトで表示する方法がわかる方教えてください)
画面にDiv要素が表示されていて、リサイズするとdiv内に表示しているwidthの値が変更されるサンプルになります。
解説
まずは、コンポーネントで保持するwidthのstateとdiv要素への参照を定義します。
const [width, setWidth] = useState<number | undefined>();
const ref = useRef<HTMLDivElement>(null);
次にResizeObserverを定義します。その際のコールバック関数として、サイズ変更を検出したときの処理を渡します。ここでは、stateの更新処理を行っていますので、DOM要素のサイズ変更が行われるたびにコンポーネントがリレンダリングされることになります。
const elm = ref.current;
const observer = new ResizeObserver(() => setWidth(elm?.offsetWidth));
observe()、unobserve()は、それぞれパラメーターで設定した要素のサイズ監視を開始、終了するメソッドです。useEffectで監視を開始し、クリーンアップ時に監視を終了しています。
if (elm) {
observer.observe(elm);
}
return () => {
elm ? observer.unobserve(elm) : "";
};