at backyard

Color my life with the chaos of trouble.

useRefを使って指定したDOMのサイズを取得する方法

最近、表題のような処理を書くべき状況になったのだが、うまく書けなかったので、反省の意味を込めて書いていく。

useRef を用いて対象のDOMを取得

useRef を使うと対象のDOMを取得できる。

https://ja.reactjs.org/docs/hooks-reference.html#useref

Ref と DOM – React

例えば document.getElementByIddocument.querySelectorなどを使ってDOMを取得して、DOM自体のサイズを計測するような場面でuseRefを用いることで同様の処理を実現することが可能となる。

Reactを用いているなら、document.getElementByIddocument.querySelectorを使ってDOMを取得するよりは useRef または createRef を用いたほうが単一方向のデータフローの中で処理を書けるので良い。

document.getElementById などを用いた場合、想定外のところでDOMの書き換えが起こることもあるため、場合によっては意図しない値を取得してしまうこともある。

もちろん、コードの状況によっては useRefを使ってうまく処理を書いていくのが大変な場合もある。ただ、後々の管理コストを考えるとやはり早いうちに useRef などを使って見通しの良い構造を作っておいたほうが良くはある。

なので、ここらへんは頑張りたいところ。
(が、もちろんケースバイケースではある)

前置きが長くなったが、下記はuseRefを使って指定したDOMのサイズを取得する方法となる。

CodeSandboxはこちら

CodeSandbox上で dataListstyles の中身を書き換えてみると、実際に取得できている横幅と縦幅が変わってくるのがわかる。

上に貼ってあるコードのサンプルを下にも貼っておく。

import "./styles.css";
import { useEffect, useRef } from "react";

const dataList = [
  { id: "1", name: "test1" },
  { id: "2", name: "test2" },
  { id: "3", name: "test3" }
];

const styles = {
  width: 500,
  height: 350
};

export default function App() {
  const elm = useRef(null);

  useEffect(() => {
    const { clientWidth, clientHeight } = elm.current;
    console.log({ clientWidth });
    console.log({ clientHeight });
  }, []);

  return (
    <div className="App" ref={elm} style={{ ...styles }}>
      <h1>Hello React</h1>
      {dataList.map((data) => (
        <p key={data.id}>
          id: {data.id}
          <br />
          name: {data.name}
        </p>
      ))}
    </div>
  );
}