🐮
React の useState と useRef、何が違うの?再レンダーの仕組みから理解する
導入
React を書いていると、useState と useRef の使い分けで迷うことがあります。
特に「値を保持したいけど、再レンダーはさせたくない」という場面で、
どっちを使えばいいのかと思ったこと、ありませんか?
この記事では、「再レンダー」「再マウント」の違いも踏まえて
useState と useRef の本質を整理します。
再レンダーと再マウントの違い
| 用語 | 意味 | 何が起きる? |
|---|---|---|
| 再レンダー (re-render) | 同じコンポーネントのインスタンスで再描画 | state や ref は保持される |
| 再マウント (re-mount) | いったん破棄 → 新しく作り直し | state や ref がリセットされる |
key が変わると再マウント、
state の変更などが起きると再レンダーです。
再レンダー・再マウント時にどうなるか
| フック/値 | 再レンダー時 | 再マウント時 |
|---|---|---|
useState |
値は保持 | 初期化される |
useRef |
値は保持 | 初期化される |
useMemo / useCallback
|
依存が変わらなければ保持 | 再計算される |
useEffect |
依存が変われば再実行 | 初回から再実行(アンマウント → マウント) |
| DOM ノード | 差分更新 | 一度破棄して再生成 |
つまり「再レンダー」は“同じインスタンス内で再評価”、
「再マウント」は“まったく新しいインスタンスに差し替え”です。
useState と useRef の違い
| 項目 | useState | useRef |
|---|---|---|
| 値を変えると再レンダー? | する | しない |
| UI に影響する値に向いてる? | 向いてる | 向いてない |
| 一時的な値を覚えておくのに向いてる? | 不向き | 向いてる |
| 更新方法 | setValue(newVal) |
ref.current = newVal |
| 再レンダー間で値を保持する? | する | する |
例:カウンター(useState)
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
count: {count}
</button>
);
}
クリック → setCount → 再レンダー発生 → UI 更新。
例:useRef で再レンダーしない値を保持
function Timer() {
const startTime = useRef(Date.now());
useEffect(() => {
const id = setTimeout(() => {
console.log("経過時間(ms):", Date.now() - startTime.current);
}, 5000);
return () => clearTimeout(id);
}, []);
return <p>5秒後にコンソールに出ます</p>;
}
useRef の値は変わっても再レンダーしない。
UI に出さない“裏の状態”を持つのに最適。
💬 使い分け
| 状況 | 使うべきフック |
|---|---|
| UI に表示される値 | useState |
| タイマーID・前回の値・スクロール位置など | useRef |
| 値を変えてもUIを変えたくない | useRef |
| 値を変えたらUIも更新したい | useState |
まとめ
React の「状態管理フック」は、
「UIに影響するかどうか」と「再レンダーを起こしたいかどうか」で使い分ける。
UIのための状態 → useState
ロジックのためのメモ → useRef
Discussion