使い方
1. useRefでrefオブジェクトを作る
const myRef = useRef(初期値);
• refフックでは、オブジェクト内でcurrentとして値が保存されます
{ current: 初期値 }
2. 値を保存・更新する
myRef.current = myRef.current + 1;
• refの値はcountRef.current
でいつでも参照・変更できる
• refの値を更新しても画面は自動で変わらない
refフックの役割
Reactコンポーネント内で再レンダーに影響しない値を保持するための仕組みです。
-
再レンダーに使わない値の保存
例えば、タイマーIDや外部APIのオブジェクト、前回の値など、UIの表示やレンダーに直接関係しない情報を保存します。
-
値の永続化
refで保持した値は、コンポーネントが再レンダーされても消えません。useRef
で作ったrefは、コンポーネントのライフサイクル中ずっと同じオブジェクトです。
-
HTML要素の操作
refを使うと、Reactの中から画面にある入力欄やボタンなどの部品(DOM要素)を直接操作できます。たとえば、ボタンを押したときに入力欄に自動でカーソルを移動させたいときなどに使います。
再レンダーに使わない値の保存とは
Reactでは、画面に表示する内容が変わると「再レンダー」が起きます。
場合によっては、画面の表示には関係ないけど、プログラムの中で覚えておきたい情報もあります。
こういう情報を保存するのにrefが使われます。
例:タイマーIDや前回の値 
タイマーIDの保存 
たとえば、setInterval
やsetTimeout
を使うとき、
返ってくる「ID」をどこかに保存しておかないと、あとで止めたり消したりできません。
このIDは画面の表示には関係ないので、stateではなくrefに保存します。
import { useRef, useState } from 'react';
// 入力欄の現在の値と、前回の値を表示するコンポーネント
function InputComponent() {
// 入力欄の現在の値を管理するstate
const [value, setValue] = useState('');
// 前回の値を保存するref(再レンダーしても値が保持されるが、画面表示には使わない)
const prevValueRef = useRef('');
// 入力欄の値が変わったときに呼ばれる関数
function handleChange(e) {
prevValueRef.current = value; // 今の値を「前回の値」としてrefに保存
setValue(e.target.value); // 入力欄の値を更新
}
return (
<>
{/* 入力欄。valueで現在の値を表示し、onChangeで入力を検知 */}
<input value={value} onChange={handleChange} />
{/* 前回の値を表示。refの値は再レンダーしても保持される */}
<div>前回の値: {prevValueRef.current}</div>
</>
);
}
ref のベストプラクティス
-
Reactの仕組みだけではできないこと」を実現するための“最後の手段”として使う
DOM要素への直接アクセスや、タイマーIDなど「画面表示に関係しない値の保存」に使います。
-
レンダー中にref.currentを読み書きしない
レンダー中にref.currentを使うと、Reactの動きが予測しづらくなります。
どうしても必要な場合(初回だけ値をセットするなど)以外は、イベントハンドラや副作用(useEffectなど)の中で使いましょう。