0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[React][Hooks] `useRef` の使い方

0
Last updated at Posted at 2025-08-04

概要

  • Reactアプリケーションで、DOM要素へのアクセスレンダー間での値保持を実現できる useRef フックを紹介

  • useRef は本質的に次の2つの役割を持つ:

    1. DOM 要素への参照を保持する
    2. 再レンダリングを引き起こさない値を保持する
  • useStateと異なり、値を更新しても再レンダリングが発生しない

  • タイマー管理、前回値の保持、フォーム制御、外部ライブラリ連携などに有効

useRef フックによって
「DOMを安全に操作できる」かつ「UIに影響しない値を保持できる」

実施条件

  • React + TypeScript プロジェクトが構築済みであること
  • React Hooksの基本(useState, useEffect など)を理解していること
  • DOMやイベントの基礎知識があること(フォーム、タイマー、描画など)

環境

ツール バージョン 目的
Node.js 22.5.1 Reactアプリ実行環境
React 19.1.0 UI構築
TypeScript 4.9 型定義による安全な開発

useRef<T>(初期値) の役割

  • useRef のジェネリクス <T> は、ref.current がどんな型の値を持つかをTypeScriptに伝える
役割 説明
DOM 要素への参照を保持する ref.current に実際の DOM 要素が入る
再レンダリングを引き起こさない値を保持する 値を変更しても UI は再描画されない

useRef の基本構造

  1. importセクション
  2. 型定義セクション
  3. 関数定義セクション
    3.1 内部状態管理セクション
    3.2 副作用(useEffect)処理セクション
    3.3 返り値構築・ロジックセクション

基本構文: useRef の使い方

// 1. importセクション
import React, { useRef, useEffect } from 'react';

// 2. 型定義セクション
// 今回は特に不要(DOM型は自動推論されるが、明示する場合はRefObject型を利用)

// 3. 関数定義セクション
const InputFocus = () => {
  // 3.1 内部状態管理セクション
  const inputRef = useRef<HTMLInputElement>(null);

  // 3.2 副作用処理セクション
  useEffect(() => {
    inputRef.current?.focus(); // 初回マウント時に自動でフォーカス
  }, []);

  // 3.3 返り値構築・ロジックセクション
  return (
    <div style={{ padding: '1rem' }}>
      <label>名前: </label>
      <input ref={inputRef} type="text" placeholder="ここに入力" />
    </div>
  );
};

export default InputFocus;

inputRef = useRef<HTMLInputElement>(null) と書くことで、TypeScriptが inputRef.current の型を自動で認識できるようになる。

活用例

1. タイマー管理:setTimeout を使って再レンダリングなしにタイマーを制御

// 1. importセクション
import React, { useRef, useEffect } from 'react';

// 2. 関数定義セクション
const TimerComponent = () => {
  // 3.1 内部状態管理セクション
  const timerRef = useRef<NodeJS.Timeout | null>(null);

  // 3.2 副作用処理セクション
  useEffect(() => {
    timerRef.current = setTimeout(() => {
      console.log('3秒後に実行されました');
    }, 3000);

    return () => {
      if (timerRef.current) clearTimeout(timerRef.current);
    };
  }, []);

  // 3.3 返り値構築・ロジックセクション
  return <p>3秒後にコンソールにログが出力されます</p>;
};

export default TimerComponent;

timerRef = useRef<NodeJS.Timeout | null>(null) と書くことで、TypeScriptが timeRef.current の型を自動で認識できるようになる。

  • setTimeout: 第1引数:遅延実行したい関数(コールバック)、第2引数:遅延時間(ミリ秒)
  • clearTimeout: setTimeout でセットしたタイマーをキャンセルする

2. フォーカス制御:ボタンクリックで任意のinputにフォーカスを当てる

// 1. importセクション
import React, { useRef } from 'react';

// 2. 関数定義セクション
const FocusOnClick = () => {
  // 3.1 内部状態管理セクション
  const inputRef = useRef<HTMLInputElement>(null);

  // 3.3 返り値構築・ロジックセクション
  const handleClick = () => {
    inputRef.current?.focus();
  };

  return (
    <div style={{ padding: '1rem' }}>
      <input ref={inputRef} type="text" placeholder="ここにフォーカスされます" />
      <button onClick={handleClick} style={{ marginLeft: '1rem' }}>
        フォーカスする
      </button>
    </div>
  );
};

export default FocusOnClick;

3. 前回値の保持:状態の前回値を useRef に記録する

// 1. importセクション
import React, { useState, useEffect, useRef } from 'react';

// 2. 関数定義セクション
const PreviousValue = () => {
  // 3.1 内部状態管理セクション
  const [count, setCount] = useState(0);
  const prevCountRef = useRef<number>(0);

  // 3.2 副作用処理セクション
  useEffect(() => {
    prevCountRef.current = count;
  }, [count]);

  // 3.3 返り値構築・ロジックセクション
  return (
    <div style={{ padding: '1rem' }}>
      <p>現在の値: {count}</p>
      <p>前回の値: {prevCountRef.current}</p>
      <button onClick={() => setCount((c) => c + 1)}>+1</button>
    </div>
  );
};

export default PreviousValue;

prevCountRef = useRef<number>(0) と書くことで、TypeScriptが prevCountRef.current の型を自動で認識できるようになる。

  • count が更新されるたびにこの副作用が走る
  • つまり、次回の更新時には prevCountRef.current に「前回のcount値」が入っている状態になる

useRef の用途まとめ

大分類 ユースケース 解説
DOM 要素への参照を保持する DOMアクセス focus(), click() など
外部ライブラリ連携 canvas / chart / map 初期化
再レンダリングを引き起こさない値を保持する タイマー管理 setTimeout ID 保持
状態の永続保持 内部カウンタなど
前回値の保持 useEffectと組み合わせる

HTMLタグおよびタイマーIDのTypeScript型対応表

種類 具体例 TypeScriptでの型名 用途例
HTMLタグ <div> HTMLDivElement DOMの操作(背景色、レイアウトなど)
<button> HTMLButtonElement ボタンのクリック処理など
<input> HTMLInputElement フォーム入力、フォーカス制御など
タイマー管理 setTimeout() など NodeJS.Timeout(Node.js) タイマーID管理、clearTimeout() に使用
setTimeout() など number(ブラウザ) タイマーID管理、clearTimeout() に使用

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?