1
1

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入門③

1
Last updated at Posted at 2026-06-02

💡はじめに

Reactでは「Hooks」を使用することで、状態管理やライフサイクル処理などを関数コンポーネント内で簡単に実装できます。
Hooksを理解することで、Reactの動きやコンポーネントの仕組みを理解しやすくなります。

この記事では、Reactでよく使用されるHooksについて、簡単なサンプルコードを交えながら紹介していきます。

できるだけシンプルにまとめているので、React学習中の方の参考になれば幸いです。

✈️関連記事はこちら
React Hooks入門①
React Hooks入門②

👍こんな人におすすめ

・最近Reactを勉強し始めた
・Reactをもう少し理解したい
・使用経験のないHooksを理解したい
・さくっと学びたい

🚩React Hooks

目次

15.useDebugValue
16.useOptimistic
17.useActionState
18.useFormStatus
19.useInsertionEffect
20.use

15.useDebugValue

useDebugValueは、Custom Hookの状態をReact DevToolsへ表示するためのHookです。
通常の画面上では変化ありませんが、Hookの状態を分かりやすく確認できるようになります。
主にcustomHook開発時やデバッグ用途で利用されます。

App.jsx
import './App.css';
import useStatus from './useStatus';

function App() {

  const {
    isOnline,
    toggleStatus
  } = useStatus();

  return (
    <div>
      <h1>useDebugValue</h1>

      <p>
        ステータス:
        {isOnline ? 'Online' : 'Offline'}
      </p>

      <button onClick={toggleStatus}>
        切り替え
      </button>
    </div>
  );
}

export default App;
useStatus.jsx
import {
  useDebugValue,
  useState
} from 'react';

const useStatus = () => {

  const [isOnline, setIsOnline] = useState(true);

  // DevToolsへ表示
  useDebugValue(
    isOnline ? 'Online' : 'Offline'
  );

  const toggleStatus = () => {
    setIsOnline(!isOnline);
  };

  return {
    isOnline,
    toggleStatus
  };
};

export default useStatus;

useDebugValue()は以下のように記述します。

useDebugValue(表示したい値);

今回の場合は、React DevToolsへ現在の状態を表示しています。

useDebugValue(
  isOnline ? 'Online' : 'Offline'
);

画面上では特に変化ありませんが、React DevToolsを確認するとcustomHookの状態を確認できます。

例えば以下のような場面で利用されます。

・customHookのデバッグ
・状態確認
・Hook開発
・DevTools表示改善

主に開発時やデバッグ用途で利用されるHookです。

16.useOptimistic

useOptimisticは、非同期処理完了前に画面を先に更新できるHookです。
API通信などでは、レスポンスを待つまで画面更新が遅れる場合があります。
useOptimisticを使用することで、処理成功を前提として先にUIを更新できます。
API通信が失敗した場合は、エラーメッセージを表示したり元の状態に戻したりする処理が必要です。

import { useOptimistic, useState } from 'react';
import './App.css';

function App() {

  const [messages, setMessages] = useState([]);

  // 楽観的更新
  const [optimisticMessages, addOptimisticMessage]
    = useOptimistic(
      messages,
      (state, newMessage) => [
        ...state,
        newMessage
      ]
    );

  const handleSubmit = async () => {
    const newMessage = 'メッセージ';

    addOptimisticMessage(newMessage);

    try {
      await new Promise((resolve) =>
        setTimeout(resolve, 1000)
      );

      setMessages((prev) => [
        ...prev,
        newMessage
      ]);
    } catch (error) {
      console.error(error);
      // エラー表示やロールバック処理を行う
    }
};

  return (
    <div>
      <h1>useOptimistic</h1>

      <button onClick={handleSubmit}>
        追加
      </button>

      <ul>
        {optimisticMessages.map((message, index) => (
          <li key={index}>
            {message}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

useOptimisticは以下のように記述します。

const [
  optimisticState,
  addOptimistic
] = useOptimistic(
  state,
  updateFunction
);
名前 内容
optimisticState 一時的な状態  
addOptimistic 楽観的更新関数
state 元の状態
updateFunction 更新処理

今回の場合は、API通信完了前にメッセージを画面へ表示しています。

addOptimisticMessage(newMessage);

その後、非同期処理完了後に実際の状態を更新しています。

setMessages((prev) => [
  ...prev,
  newMessage
]);

※ 実務では、リストのkeyにはindexではなく、データが持つidなど一意な値を使うのが望ましいです。

{optimisticMessages.map((message, index) => (
  <li key={index}>
    {message}
  </li>
))}

これにより、ユーザーは待ち時間を感じにくくなります。
例えば以下のような場面で利用されます。

・チャット送信
・コメント投稿
・いいね機能
・お気に入り登録

API通信の完了を待たずに画面を更新したい場合に利用されるHookです。

17.useActionState

useActionStateは、フォーム送信などのアクション結果を管理できるHookです。
フォーム送信時の状態管理やエラーメッセージ表示を簡単に実装できます。
React19で追加されたHookです。

import { useActionState } from 'react';
import './App.css';

// action
const submitForm = async (prevState, formData) => {

  const name = formData.get('name');

  // 入力チェック
  if (!name) {
    return {
      success: false,
      message: '名前を入力してください'
    };
  }

  // API通信を想定
  await new Promise((resolve) =>
    setTimeout(resolve, 1000)
  );

  return {
    success: true,
    message: `${name} を登録しました`
  };
};

function App() {

  const [state, formAction, isPending]
    = useActionState(
      submitForm,
      {
        success: false,
        message: ''
      }
    );

  return (
    <div>
      <h1>useActionState</h1>

      <form action={formAction}>

        <input
          type="text"
          name="name"
          placeholder="名前"
        />

        <button type="submit">
          送信
        </button>

      </form>

      {isPending && <p>送信中...</p>}

      <p>{state.message}</p>
    </div>
  );
}

export default App;

useActionStateは以下のように記述します。

const [
  state,
  formAction,
  isPending
] = useActionState(
  action,
  initialState
);
名前 内容
state 現在の状態
formAction form用action
isPending 処理中状態
action 実行処理
initialState 初期値

今回の場合は、フォーム送信時にsubmitForm()が実行されます。

<form action={formAction}>

入力値はformDataから取得できます。

const name = formData.get('name');

送信中はisPendingがtrueになるため、ローディング表示も可能です。

{isPending && <p>送信中...</p>}

例えば以下のような場面で利用されます。

・フォーム送信
・ログイン処理
・バリデーション
・非同期アクション管理

フォーム関連処理をシンプルに管理したい場合に利用されるHookです。

18.useFormStatus

useFormStatusは、フォーム送信中の状態を取得できるHookです。
React19で追加されたHookで、フォーム送信中のローディング表示やボタンの制御を簡単に実装できます。
通常はuseActionStateと組み合わせて利用します。

App.jsx
import { useActionState } from 'react';
import SubmitButton from './SubmitButton';
import './App.css';

const submitForm = async (prevState, formData) => {

  await new Promise((resolve) =>
    setTimeout(resolve, 2000)
  );

  return {
    message: '送信完了'
  };
};

function App() {

  const [state, formAction] = useActionState(
    submitForm,
    {
      message: ''
    }
  );

  return (
    <div>
      <h1>useFormStatus</h1>

      <form action={formAction}>

        <input
          type="text"
          name="name"
          placeholder="名前"
        />

        <SubmitButton />

      </form>

      <p>{state.message}</p>
    </div>
  );
}

export default App;
SubmitButton.jsx
import { useFormStatus } from 'react-dom';

function SubmitButton() {

  const { pending } = useFormStatus();

  return (
    <button
      type="submit"
      disabled={pending}
    >
      {pending ? '送信中...' : '送信'}
    </button>
  );
}

export default SubmitButton;

useFormStatus()は以下のように記述します。

const { pending } = useFormStatus();

pending・・・フォーム送信中かどうか
今回の場合は、フォーム送信中にボタンを無効化しています。

<button
  type="submit"
  disabled={pending}
>

また、送信中はボタンの表示を変更しています。

{pending ? '送信中...' : '送信'}

これにより、ユーザーが連続で送信ボタンを押してしまうことを防げます。

例えば以下のような場面で利用されます。

・お問い合わせフォーム
・ログイン画面
・会員登録画面
・データ登録処理

フォーム送信中の状態管理を簡単に行いたい場合に利用されるHookです。

19.useInsertionEffect

useInsertionEffectは、useLayoutEffectより前に実行されるHookで、主にCSS-in-JSライブラリがスタイルを挿入するために利用されます。
通常のアプリケーション開発で直接使うことはほとんどありません。

import {
  useInsertionEffect,
  useState
} from 'react';

import './App.css';

function App() {

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

  useInsertionEffect(() => {

    console.log('useInsertionEffect 実行');

  }, [count]);

  return (
    <div>
      <h1>useInsertionEffect</h1>

      <p>count:{count}</p>

      <button
        onClick={() => setCount(count + 1)}
      >
        カウントアップ
      </button>
    </div>
  );
}

export default App;

このサンプルでは動作確認のためにconsole.logを出していますが、実際にはCSS-in-JSライブラリなどがスタイルを挿入する用途で利用するHookです。
通常のアプリ開発ではほとんど使いません。

useInsertionEffectは以下のように記述します。

useInsertionEffect(() => {

  実行したい処理

}, [監視する値]);

今回の場合は、countが変更されるたびに処理が実行されます。

useInsertionEffect(() => {

  console.log('useInsertionEffect 実行');

}, [count]);

useEffectやuseLayoutEffectとの実行タイミングの違いは以下の通りです。

Hook 主な実行タイミング・用途
useInsertionEffect useLayoutEffectより前。主にCSS-in-JSのスタイル挿入用
useLayoutEffect DOM更新後、ブラウザ描画前に同期的に実行
useEffect ブラウザ描画後に実行されることが多い

例えば以下のような場面で利用されます。

・CSS-in-JSライブラリ
・スタイルの動的挿入
・ライブラリ開発

useInsertionEffectは、レイアウト計算が行われる前にスタイルを挿入するための特殊なHookです。
一般的なReactアプリではほとんど利用されませんが、Reactが提供しているHookの1つです。

20.use

useは名前がuseから始まりますが、useStateやuseEffectのような通常のHookとは少し性質が異なります。
通常のHooksは条件分岐やループの中で呼び出せませんが、useは条件分岐やループの中で呼び出すことができます。

import { Suspense, use } from 'react';
import './App.css';

// API通信を想定
const fetchUser = () => {

  return new Promise((resolve) => {

    setTimeout(() => {

      resolve({
        name: 'React User'
      });

    }, 2000);

  });
};

const userPromise = fetchUser();

function UserInfo() {

  const user = use(userPromise);

  return (
    <p>ユーザー名{user.name}</p>
  );
}

function App() {

  return (
    <div>
      <h1>use</h1>

      <Suspense fallback={<p>読み込み中...</p>}>
        <UserInfo />
      </Suspense>
    </div>
  );
}

export default App;

useでPromiseを読み込む場合、Promiseが完了するまでコンポーネントはSuspenseによって待機状態になります。
そのため、Suspenseのfallbackを用意する必要があります。

use()は以下のように記述します。

const data = use(promise);

Promiseの処理が完了するまで待機し、完了後に値を取得できます。

const user = use(userPromise);

今回の場合は、API通信を想定したPromiseからユーザー情報を取得しています。
従来の実装では以下のように記述することが一般的でした。

const [user, setUser] = useState(null);

useEffect(() => {

  fetchUser().then((data) => {
    setUser(data);
  });

}, []);

use()を使用することで、非同期処理をよりシンプルに記述できます。

例えば以下のような場面で利用されます。

・API通信
・非同期データ取得
・Server Components
・Contextの取得

React19で追加された新しいHookで、今後利用機会が増えていくHookの1つです。


✈️関連記事
React Hooks入門①

React Hooks入門②

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?