---
title: "Reactフック（Hooks）とは？全18種の一覧とReact Compiler時代の使い分け【2026年8月版】"
url: "https://www.issoh.co.jp/tech/details/3671/"
published: 2024-09-27
updated: 2026-08-02
categories: ["React"]
publisher: "株式会社一創"
---

# Reactフック（Hooks）とは？全18種の一覧とReact Compiler時代の使い分け【2026年8月版】

Reactフックは、関数コンポーネントから状態や副作用といったReactの機能へ接続するための関数です。React 16.8で10種類から始まった仕組みは、2026年8月時点の最新版 react 19.2.8 で18種類まで増えました。同時に、React Compiler 1.0の登場で `useMemo` と `useCallback` を手で書く前提そのものが崩れています。この記事では、現行バージョンのフック全18種を一覧で整理したうえで、実装で使う順に使い方と判断基準をまとめます。

## まとめ

react 19.2.8 が公開するフックは18種類です。`react-dom` 側の `useFormStatus` を足せば19種類、旧APIの `useFormState` まで数えれば20種類という数え方もできます。名前が似ている `use` は公式ドキュメントが「フックではない」と明記しているため、この18種には含めません。記事によってフックの総数が違うのは、この境界の引き方が違うためです。

使い分けの結論を先に書きます。状態は `useState`、状態遷移が3パターン以上に増えたら `useReducer`。副作用は `useEffect` ですが、データ取得は原則ライブラリに任せます。React 19.2で追加された `useEffectEvent` を使えば、依存配列に入れたくない処理をEffectの外へ逃がせます。そして React Compiler 1.0 を導入した環境では、`useMemo`・`useCallback`・`React.memo` の手書きは原則不要になりました。フックのルールにも「try/catch/finally の中で呼ばない」が明記されています。以降で、この判断の根拠を一次情報とコードで示します。

## Reactフック全18種の一覧と分類

### 分類別の早見表

| 分類     | フック                  | 主な用途              | 追加バージョン |
| ------ | -------------------- | ----------------- | ------- |
| 状態     | useState             | 状態の宣言と更新          | 16.8    |
| 状態     | useReducer           | reducerで状態遷移を集約   | 16.8    |
| アクション  | useActionState       | アクションの実行状態を管理     | 19.0    |
| アクション  | useOptimistic        | 楽観的UIの一時状態        | 19.0    |
| コンテキスト | useContext           | コンテキストの購読         | 16.8    |
| 参照     | useRef               | 再レンダリングを起こさない値の保持 | 16.8    |
| 参照     | useImperativeHandle  | refで公開する値の制御      | 16.8    |
| 副作用    | useEffect            | 外部システムとの同期        | 16.8    |
| 副作用    | useLayoutEffect      | 描画前のレイアウト計測       | 16.8    |
| 副作用    | useInsertionEffect   | CSS-in-JSの動的挿入    | 18.0    |
| 副作用    | useEffectEvent       | 依存配列に載せない処理の切り出し  | 19.2    |
| 性能     | useMemo              | 計算結果のキャッシュ        | 16.8    |
| 性能     | useCallback          | 関数定義のキャッシュ        | 16.8    |
| 性能     | useTransition        | 更新をノンブロッキング化      | 18.0    |
| 性能     | useDeferredValue     | 非優先UIの更新を遅延       | 18.0    |
| その他    | useId                | 一意なID生成           | 18.0    |
| その他    | useSyncExternalStore | 外部ストアの購読          | 18.0    |
| その他    | useDebugValue        | DevTools表示ラベルの指定  | 16.8    |

react 19.2.8 が `use` で始まる名前で公開するエクスポートは19個で、フックではない `use` を除くと18種になります。react.dev のフックリファレンスに並ぶ数とも一致します。なお上表の分類列は読み進める順に整理した本記事独自のもので、react.dev は `useActionState` を「その他」に置いています。フォーム送信状態を読む `useFormStatus` だけは `react` ではなく `react-dom` から提供されます。同じく `react-dom` にある `useFormState` は `useActionState` に置き換わった旧APIなので、新規実装では使いません。

### useがフック18種に入らない理由

Promiseやコンテキストを読み取る `use` は名前が `use` で始まりますが、公式リファレンスは「Despite its name, `use` is not a Hook.（名前に反して、useはフックではない）」と明記しています。実装上の違いははっきりしていて、「Unlike Hooks, it can be called inside loops and conditional statements like `if`.（フックと異なり、ループや if などの条件分岐の中で呼び出せる）」とされています。

つまりフックのルールが縛る「トップレベルでのみ呼ぶ」という制約を `use` は受けません。条件分岐でPromiseを出し分けたい場面ではこの差が効いてきます。Suspenseとの組み合わせや、クライアントコンポーネントでPromiseをキャッシュしないと再レンダリングのたびにフォールバックへ戻ってしまう落とし穴は、[Reactのuseフック（use API）の使い方——React 19のPromise・Context読み取りを解説](/tech/details/2989/)で個別に扱っています。

## useStateとuseReducer：状態の宣言と切り替えの基準

### useStateの基本と更新関数を使うべき場面

`useState` は `const [値, 更新関数] = useState(初期値)` の形で宣言し、状態変数と更新関数のペアを受け取るフックです。更新関数を呼ぶとコンポーネントが再レンダリングされます。つまずきやすいのは、同じイベント内で複数回更新するケースです。

```
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const addTwice = () => {
    // 直前の値に依存する更新は、値ではなく更新関数を渡す
    setCount(c => c + 1);
    setCount(c => c + 1); // 2 増える。setCount(count + 1) を2回書くと 1 しか増えない
  };

  return <button onClick={addTwice}>{count}</button>;
}
```

`setCount(count + 1)` を2回書くと、どちらも同じレンダリング時点の `count` を参照するため1しか増えません。直前の値に依存する更新では必ず更新関数を渡します。

### オブジェクト・配列の状態を壊さない更新の書き方

Reactは状態の変化を `Object.is` による参照比較で判定します。元のオブジェクトや配列を直接書き換えても参照が変わらないため、再レンダリングは起きません。

```
const [form, setForm] = useState({ name: '', email: '' });

// 既存プロパティを保ったまま1つだけ差し替える
setForm(prev => ({ ...prev, email: 'sales@example.com' }));

const [items, setItems] = useState([]);

// push は同じ配列参照を返すので再レンダリングされない。新しい配列を作る
setItems(prev => [...prev, newItem]);
```

フォームのように項目が10個を超えると、この展開が毎回のイベントハンドラに散らばって読みにくくなります。バリデーションも絡む規模なら、状態管理ごと [React Hook Formとは？使い方・バリデーション・v7の書き方を実例で解説](/tech/details/2898/)で扱っているようなフォーム専用ライブラリに寄せた方が保守しやすくなります。

### useReducerへ切り替える判断基準

切り替えの目安は「状態遷移のパターンが3つ以上あり、しかも複数の状態が連動して変わるか」です。送信中・成功・失敗のように `status` と `error` が必ずセットで変わる場合、`useState` を2つ並べると片方だけ更新し忘れる不整合が起きます。

```
import { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'submitted':
      return { status: 'sending', error: null };
    case 'succeeded':
      return { status: 'done', error: null };
    case 'failed':
      return { status: 'idle', error: action.message };
    default:
      throw new Error('unknown action: ' + action.type);
  }
}

const [state, dispatch] = useReducer(reducer, { status: 'idle', error: null });
```

逆に、独立したboolean1つやテキスト入力1つに `useReducer` を使うのは冗長です。reducerの定義とアクション型の管理コストが、得られる見通しの良さを上回ります。アプリ全体でグローバルな状態を共有する段階まで来たら、[Redux Toolkitとは？createSliceとRTK Queryの実装と採用判断【2026年8月版】](/tech/details/16013/)で解説している専用ライブラリの導入を検討する時期です。

## useEffectと副作用：クリーンアップとuseEffectEvent

### useEffectの実行タイミングとクリーンアップ関数

`useEffect` はコンポーネントを外部システムへ接続するためのフックです。返り値のクリーンアップ関数は、アンマウント時だけでなく依存配列の値が変わる直前にも呼ばれます。

```
useEffect(() => {
  const conn = createConnection(roomId);
  conn.connect();

  // 依存配列の値が変わる直前と、アンマウント時に呼ばれる
  return () => conn.disconnect();
}, [roomId]);
```

この「変わる直前にも呼ばれる」性質が抜けていると、`roomId` が切り替わるたびに古い接続が残り続けます。開発環境のStrict Modeがマウントを2回実行するのは、まさにこのクリーンアップ漏れを検出するためです。

### useEffectEventによる依存配列からの処理分離（React 19.2）

React 19.2（2025年10月1日リリース）で追加された `useEffectEvent` は、Effect内から呼ばれるが再実行のトリガーにはしたくない処理を切り出します。

```
import { useEffect, useEffectEvent } from 'react';

function ChatRoom({ roomId, theme }) {
  // theme を読んでも Effect の再実行トリガーにはならない
  const onConnected = useEffectEvent(() => {
    showNotification('接続しました', theme);
  });

  useEffect(() => {
    const conn = createConnection(roomId);
    conn.on('connected', () => onConnected());
    conn.connect();
    return () => conn.disconnect();
  }, [roomId]); // theme を依存配列に入れずに済む
}
```

従来は `theme` を依存配列に入れるとテーマ切り替えのたびに再接続が走り、外すとlintに警告されるというジレンマがありました。`useEffectEvent` でラップした関数は最新の値を読みつつ依存配列に載せずに済むため、この板挟みが解消します。19.2で入った他の変更は[React 19.2の新機能総まとめ：<Activity>コンポーネントやuseEffectEvent、cacheSignalなど注目ポイント徹底解説](/tech/details/9427/)にまとめています。

### データ取得をuseEffectで書かない判断

旧来の入門記事はデータ取得の例として `useEffect` の中で `fetch` を呼びます。この形は、競合状態・キャッシュ不在・重複リクエスト・エラー再試行を自前で書くことになり、実務では割に合いません。

クライアント側で取得するなら [TanStack Queryとは？React Queryとの違い・v5の使い方と脆弱性対策](/tech/details/10307/)のようなデータ取得ライブラリを使い、サーバー側で取得できるならReact Server Componentsに寄せます。`useEffect` を使うのは、WebSocket接続やイベントリスナー登録のように「外部システムとの同期」が本質である場面に絞ってください。

## useContextとuseRef：値の共有と再レンダリングの回避

### useContextによるprops受け渡しの省略

`useContext` は、propsを何階層も手渡しせずに値を配るためのフックです。React 19からはProviderを書かずコンテキスト自体をレンダーできるようになりました。公式リファレンスは「Starting in React 19, you can render `<SomeContext>` as a provider.」と記載しています。

```
import { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function App() {
  // React 19 以降は Provider を書かずコンテキスト自体をレンダーできる
  return (
    <ThemeContext value="dark">
      <Toolbar />
    </ThemeContext>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext); // 直近の値を読む
  return <button className={theme}>送信</button>;
}
```

注意点は、コンテキストの値が変わると購読している全コンポーネントが再レンダリングされることです。更新頻度の高い値と低い値を1つのコンテキストに詰め込むと、無関係なコンポーネントまで巻き込まれます。用途ごとにコンテキストを分けるのが基本方針です。

### useRefが再レンダリングを起こさない理由

`useRef` が返すのは `current` プロパティを持つ可変オブジェクトです。この `current` を書き換えてもReactは変化を検知せず、再レンダリングは発生しません。

```
function EmailField() {
  const inputRef = useRef(null);
  const renderCount = useRef(0);

  renderCount.current += 1; // 書き換えても再レンダリングは起きない

  return <input ref={inputRef} type="email" />;
}
```

DOMノードの参照、タイマーIDの保持、前回値の記録がおもな用途です。画面に表示する値をrefへ入れると更新が反映されないので、表示に関わる値は `useState` を使います。子コンポーネントへrefを渡す方法はReact 19で変わり、`forwardRef` のラップが不要になりました。移行手順は[React 19でforwardRefが不要に｜refをpropsで渡す新方式と移行手順](/tech/details/4382/)で扱っています。

## React Compiler 1.0で不要になるフックと、残るフック

### 自動メモ化が肩代わりする範囲

2025年10月7日（UTC）に `babel-plugin-react-compiler` の1.0.0が公開され、React Compilerは安定版になりました。これはビルド時にコンポーネントを解析して自動でメモ化するコンパイラで、公式ドキュメントは手書きの `useMemo`・`useCallback`・`React.memo` が不要になると説明しています。

ここは立場を明確にしておきます。2026年8月時点で新規にReactアプリを立ち上げるなら、React Compilerを入れて手書きメモ化を書かない方針を既定にすべきです。旧来の入門記事が紙幅を割いてきた「useCallbackで関数を固定し、React.memoで子の再レンダリングを防ぐ」という一連のテクニックは、コンパイラがある環境では書く必要がないうえ、依存配列の書き間違いというバグ源を持ち込みます。

### Vite・Babelでの導入設定

```
npm install -D babel-plugin-react-compiler@latest

# Vite で reactCompilerPreset を使う場合は追加で必要
npm install -D @rolldown/plugin-babel
```

React 19との組み合わせが前提ですが、公式は「React Compiler is designed to work best with React 19, but it also supports React 17 and 18.」として17・18もサポート対象としています。Viteで `reactCompilerPreset` を使えるのは `@vitejs/plugin-react` の6.0.0以降で、6.0.0でインラインのBabelオプションが廃止されたため、上のように `@rolldown/plugin-babel` を別途入れます。

```
// vite.config.js
import { defineConfig } from 'vite';
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
import babel from '@rolldown/plugin-babel';

export default defineConfig({
  plugins: [
    react(),
    babel({ presets: [reactCompilerPreset()] }),
  ],
});
```

仕組みと既存プロジェクトへの適用手順は[React Compilerとは？自動メモ化の仕組みと導入方法・useMemoとの違いを解説](/tech/details/9415/)で詳しく扱っています。

### それでも手書きメモ化が残る場面

コンパイラを入れても消えない用途はあります。第一に、コンパイラが解析を諦めたコンポーネントです。ルールに反する書き方が残っていると最適化がスキップされるため、その箇所は従来どおりの手当てが要ります。第二に、参照の同一性そのものが仕様として必要な場合です。`useEffect` の依存配列に渡すオブジェクトや、外部ライブラリへ渡すコールバックのように、「再生成されないこと」自体に意味がある値は明示的に固定します。

なお `useTransition` と `useDeferredValue` は分類こそ性能系ですが、メモ化とは別物なのでコンパイラを入れても不要になりません。これらは重い更新の優先度を下げる仕組みで、代替になるものがありません。

## フックのルールとeslint-plugin-react-hooks 7系

### 呼び出してよい場所と、してはいけない場所

フックは関数コンポーネントかカスタムフックの本体で、トップレベルからのみ呼び出せます。公式が禁止として挙げているのは次の6つです。

- 条件分岐やループの中
- 条件付き `return` より後
- イベントハンドラの中
- クラスコンポーネントの中
- `useMemo`・`useReducer`・`useEffect` へ渡す関数の中
- `try`・`catch`・`finally` ブロックの中

最後の `try/catch/finally` 禁止は、2019年前後に書かれた解説記事にはまず載っていません。フックの呼び出し順序が実行経路によってずれる可能性があるためで、エラー処理は `use` やエラーバウンダリ側で扱います。

### 7系のプリセットとコンパイラ由来のlint

`eslint-plugin-react-hooks` は7.0.0でプリセットを整理し、`-legacy` が付く旧形式向けの設定を廃止しました。7.1.1が実際に公開している設定は `recommended`、`recommended-latest`、そして両者を格納した `flat` の3つです。ここに落とし穴があります。フラットコンフィグから読み込むのは `configs.recommended` ではなく `configs.flat.recommended` です。前者は `plugins` を配列で持つ .eslintrc 形式のままなので、そのまま `eslint.config.js` に置くと読み込み時にエラーになります。公式READMEが案内しているのも `flat` 経由の書き方です。

```
// eslint.config.js
import reactHooks from 'eslint-plugin-react-hooks';

export default [
  // フラットコンフィグでは configs.recommended ではなく configs.flat.recommended を使う
  // （configs.recommended は .eslintrc 形式のままなので読み込むとエラーになる）
  reactHooks.configs.flat.recommended,
];
```

7系で大きいのは、React Compiler由来のルールが既定で有効になった点です。`set-state-in-effect`（Effect内での状態更新）、`set-state-in-render`（レンダー中の状態更新）、`purity`（副作用のある式）、`immutability`、`refs` といった検査が加わり、従来の `rules-of-hooks` と `exhaustive-deps` だけでは拾えなかった問題を静的に検出できます。`recommended` が有効化するルールは合計16本。従来の2本から14本増えた計算なので、既存プロジェクトに入れれば相応の指摘が出ます。その多くはコンパイラが最適化を諦める箇所と重なるため、先に潰しておく価値があります。コードベース全体の健全性を機械的に見たい場合は[React Doctorとは？npxで使うReactコード診断ツールの使い方・スコア・ESLintとの違い](/tech/details/11069/)も併用できます。

## React 16.8から19.2までのフック追加履歴

フックがどのバージョンで何を解決するために増えてきたかを押さえておくと、記事や社内コードの前提バージョンを判断しやすくなります。

| バージョン | 時期       | 追加されたフック                                                                                                                                | 背景                       |
| ----- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| 16.8  | 2019年2月  | useState / useEffect / useContext / useReducer / useRef / useMemo / useCallback / useImperativeHandle / useLayoutEffect / useDebugValue | 関数コンポーネントで状態とライフサイクルを扱う  |
| 18.0  | 2022年3月  | useTransition / useDeferredValue / useId / useSyncExternalStore / useInsertionEffect                                                    | 並行レンダリングとSSRのhydration対応 |
| 19.0  | 2024年12月 | useActionState / useOptimistic                                                                                                          | Actionsによるフォーム送信の標準化     |
| 19.2  | 2025年10月 | useEffectEvent                                                                                                                          | 依存配列に載せない処理の分離           |

16.8のフック追加から7年が経ち、クラスコンポーネント前提のコードは実質的に保守対象のみになりました。18から19への移行時の変更点は[React 19とは？18からの変更点・新機能とReact Compiler・最新バージョンを解説](/tech/details/4509/)にまとめています。

## よくある質問

**Q. Reactフックは全部で何種類ありますか。**  
A. 2026年8月時点の最新版 react 19.2.8 が公開するフックは18種類です。`react-dom` の `useFormStatus` を含めると19種類になります。`use` は公式が「フックではない」としているため、この数には含めていません。

**Q. useStateとは何ですか。**  
A. コンポーネントに状態変数を持たせるフックです。`const [値, 更新関数] = useState(初期値)` の形で宣言し、更新関数を呼ぶとコンポーネントが再レンダリングされます。直前の値をもとに更新する場合は、値ではなく更新関数を渡してください。

**Q. React 16.8より前のバージョンでフックは使えますか。**  
A. 使えません。フックは16.8で追加された機能で、それ以前のバージョンでは状態やライフサイクルをクラスコンポーネントで書く必要があります。なおReact Compilerが対応するのは17以降です。

**Q. React Compilerを導入したら、既存のuseMemoとuseCallbackは削除すべきですか。**  
A. 一括削除は避けてください。コンパイラが最適化を適用できたかはビルド時に確認でき、適用された箇所から段階的に外すのが安全です。参照の同一性が仕様として必要な箇所は残します。

**Q. カスタムフックはどこから作るべきですか。**  
A. 同じ `useState` と `useEffect` の組み合わせが2箇所以上に現れた時点が目安です。名前は `use` で始める必要があり、この命名規則によってlintがフックのルールを適用できるようになります。

## 関連記事

- [Reactのuseフック（use API）の使い方——React 19のPromise・Context読み取りを解説](/tech/details/2989/)
- [React Compilerとは？自動メモ化の仕組みと導入方法・useMemoとの違いを解説](/tech/details/9415/)
- [React 19.2の新機能総まとめ：<Activity>コンポーネントやuseEffectEvent、cacheSignalなど注目ポイント徹底解説](/tech/details/9427/)
- [React 19とは？18からの変更点・新機能とReact Compiler・最新バージョンを解説](/tech/details/4509/)
- [React 19でforwardRefが不要に｜refをpropsで渡す新方式と移行手順](/tech/details/4382/)

---

出典: [Reactフック（Hooks）とは？全18種の一覧とReact Compiler時代の使い分け【2026年8月版】](<https://www.issoh.co.jp/tech/details/3671/>)（株式会社一創）
