最近、表題のような処理を書くべき状況になったのだが、うまく書けなかったので、反省の意味を込めて書いていく。
useRef
を用いて対象のDOMを取得
useRef
を使うと対象のDOMを取得できる。
https://ja.reactjs.org/docs/hooks-reference.html#useref
例えば document.getElementById
や document.querySelector
などを使ってDOMを取得して、DOM自体のサイズを計測するような場面でuseRef
を用いることで同様の処理を実現することが可能となる。
Reactを用いているなら、document.getElementById
や document.querySelector
を使ってDOMを取得するよりは useRef
または createRef
を用いたほうが単一方向のデータフローの中で処理を書けるので良い。
document.getElementById
などを用いた場合、想定外のところでDOMの書き換えが起こることもあるため、場合によっては意図しない値を取得してしまうこともある。
もちろん、コードの状況によっては useRef
を使ってうまく処理を書いていくのが大変な場合もある。ただ、後々の管理コストを考えるとやはり早いうちに useRef
などを使って見通しの良い構造を作っておいたほうが良くはある。
なので、ここらへんは頑張りたいところ。
(が、もちろんケースバイケースではある)
前置きが長くなったが、下記はuseRefを使って指定したDOMのサイズを取得する方法となる。
CodeSandboxはこちら
CodeSandbox上で dataList
や styles
の中身を書き換えてみると、実際に取得できている横幅と縦幅が変わってくるのがわかる。
上に貼ってあるコードのサンプルを下にも貼っておく。
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> ); }