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?

useRefでDOM操作をマスターしよう番外編

Last updated at Posted at 2025-11-03

ReactのuseRefは「DOM参照フック」だけではない

これまでの記事では、useRefのDOM操作について触れてきましたが、

実務レベルでReactを書いていると、UIには出さないけど、最新の状態を維持したい値が多く存在します。

1.スクロール座標
2.アニメーションの進捗
3.タイマーID
4.前回値
5.Web APIインスタンス
6.フラグ管理
7.イベントの最新ハンドラ

こうした値を、UIを再描画せずに持ち続けられるのがuseRefの強みです。

useRefの本質

再レンダリングさせずに“現在値”を持つ箱
useRef.current に代入してもUIは変わりません。
だからこそ、裏で動くロジック用の変数として最適です。

useRefの非DOM用途パターン

1. 高頻度で変化する値の保持(ドラッグ/カーソル/アニメ)

const posRef = useRef({ x: 0, y: 0 })

function onMove(e) {
  posRef.current = { x: e.clientX, y: e.clientY }
}

クリックした座標の位置の値なども取得可能。
マウス追従UI、ドラッグ、チャートを使用したキャンバス描画などに。

2. タイマー制御(setInterval / setTimeout)

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

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

function stop() {
  if (timerRef.current) clearInterval(timerRef.current)
}

ゲームやチャートの更新、定期データ取得などでよく使います。
タイマーのIDは画面とは関係ないので、refにメモしておくとスムーズに管理できます。

3. 前回値を記録して差分ロジック

const prevValueRef = useRef<number | null>(null)

function handle(value: number) {
  console.log("前回:", prevValueRef.current, "現在:", value)
  prevValueRef.current = value
}

スクロールが上方向か下方向か、数値が増えたか減ったかなど、
“前の値と比較して判断する”ロジックに便利です。
refに前回値を保存しておくことで、次の処理時に簡単に差分を取れます。

4. 一度だけ実行したい処理のフラグ管理

const initializedRef = useRef(false)

function initOnce() {
  if (initializedRef.current) return
  initializedRef.current = true
  console.log("初回だけ実行")
}

初期化処理、APIコール制御、
無限ループ防止フラグとして使われます。

5. Web APIやライブラリインスタンスの保持

const audioRef = useRef<HTMLAudioElement | null>(null)
const playerRef = useRef<SomePlayer | null>(null)

例:
Audio / Video API
Three.js / D3
Chart.js
WebRTC / WebSocket

レンダリングがあっても、動画の再生や画面の描画を止めないなど
外部オブジェクトをReact再レンダリングの外で持ちたいときに。

6. 重いデータのキャッシュ

const cacheRef = useRef<Map<string, any>>(new Map())

function save(key: string, data: any) {
  cacheRef.current.set(key, data)
}

APIレスポンス、計算結果など
再取得したくない一時データを保持。

“見せる”データではなく、“使う”データ向けです。

まとめ

useRefは「DOM操作のためのフック」という説明だけでは足りません。
実務では、UIではなくロジック側で動く値を扱う場面が多く存在します。

画面のレンダリングに関係する状態はstate
画面のレンダリング外で動く値はref

この意識があると、Reactコードの構造がクリアになり、
パフォーマンスの無駄も減ります。

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?