useRef

JS

使いたい場面↓

使いたい場面useRefが便利!
DOMを触りたい✅ OK
直近の値を保持したい✅ OK
でも画面を再描画したくない✅ OK

フォーカスを当てる

const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
  inputRef.current?.focus(); // フォーカスする!
}, []);

return <input ref={inputRef} />;

?について

名前意味JS/TS
a?.bオプショナルチェイニングa があるときだけ b にアクセスJS(ES2022以降) / TS
age?: numberオプショナルプロパティage はあってもなくてもOKTSのみ
function foo(a?: string)オプショナル引数引数は省略可能TSのみ

TSでよく使うDOM型の例

DOM型名対応するHTML要素説明
HTMLInputElement<input>テキスト入力、チェックボックスなど
HTMLTextAreaElement<textarea>テキストエリア
HTMLButtonElement<button>ボタン
HTMLDivElement<div>ブロック要素、レイアウト用
HTMLImageElement<img>画像
HTMLAnchorElement<a>リンク
HTMLSelectElement<select>セレクトボックス(プルダウン)
HTMLFormElement<form>フォーム全体
HTMLUListElement<ul>順不同リスト
HTMLLIElement<li>リスト項目
HTMLSpanElement<span>インライン要素
HTMLTableElement<table>テーブル全体
HTMLTableRowElement<tr>テーブルの行
HTMLTableCellElement<td> / <th>テーブルのセル
HTMLElementすべてのHTML要素汎用。ほとんどの要素がこれを継承

スクロールやサイズの取得

const divRef = useRef<HTMLDivElement>(null);

useEffect(() => {
  console.log(divRef.current?.offsetHeight);
}, []);

タイマーや外部ライブラリとの連携

const timerRef = useRef<number | null>(null);

useEffect(() => {
  timerRef.current = window.setInterval(() => {
    console.log("tick");
  }, 1000);

  return () => {
    if (timerRef.current) clearInterval(timerRef.current); // クリーンアップ
  };
}, []);

状態をリレンダーさせずに保持したいとき

const countRef = useRef(0);

const handleClick = () => {
  countRef.current++;
  console.log("クリック数:", countRef.current);
};

useStateは状態が更新されるたびにコンポーネントが再レンダリングされますが、useRefなら再レンダリングしないで値が更新されます。