【React 19.2対応】useフック(use API)の特徴と基本的な使い方

2025年1月17日React

React 19で追加されたuseは、PromiseやContextなどの値をコンポーネントのレンダー中に読み取るための新しいReact APIです。一般的には「useフック」と呼ばれることもありますが、React公式ドキュメントではuseをHookではなく「API」として説明しています。useを使うことで、非同期データの読み込みやContextの取得を、よりシンプルな形で扱えるようになります。:contentReference[oaicite:1]{index=1}

この記事では、React 19.2時点の最新情報に合わせて、useの特徴、基本的な使い方、Suspenseとの組み合わせ、注意点をわかりやすく紹介します。

React 19で追加されたuseフック(use API)とは

useは、PromiseやContextなどの「リソース」から値を読み取るためのAPIです。たとえばPromiseをuseに渡すと、Promiseが解決されるまでコンポーネントのレンダーを一時停止し、解決後にその値を取得できます。Promiseの待機中は、Suspensefallbackに指定したローディングUIを表示できます。:contentReference[oaicite:2]{index=2}

従来、クライアント側でデータを取得する場合は、useEffectuseStateを組み合わせて、ローディング状態やエラー状態を手動で管理することが多くありました。しかしuseを使うと、Suspenseと連携しながら、非同期データをより宣言的に扱えます。

useフック(use API)の主な特徴

Promiseの結果をレンダー中に読み取れる

useにPromiseを渡すと、ReactはそのPromiseが解決されるまでコンポーネントを一時停止します。Promiseが解決されると、useはその解決値を返し、コンポーネントは取得したデータを使って表示されます。:contentReference[oaicite:3]{index=3}

Suspenseと自然に連携できる

useでPromiseを読み取る場合、Promiseが未解決の間はSuspenseがローディングUIを表示します。これにより、コンポーネント側でisLoadingのような状態を細かく管理しなくても、読み込み中の表示を整理しやすくなります。:contentReference[oaicite:4]{index=4}

Contextも読み取れる

useはPromiseだけでなくContextも読み取れます。useContextと似ていますが、useは条件分岐やループの中でも呼び出せる点が特徴です。ただし、useを呼び出す関数自体は、ReactコンポーネントまたはカスタムHookである必要があります。:contentReference[oaicite:5]{index=5}

Server ComponentsとClient Componentsの連携に向いている

Reactの公式ドキュメントでは、PromiseをClient Component内で毎回作るよりも、Server Component側でPromiseを作成し、それをClient Componentにpropsとして渡す方法が推奨されています。Client Component内でPromiseをレンダーごとに作ると、再レンダーのたびにPromiseが作り直されるためです。:contentReference[oaicite:6]{index=6}

useフック(use API)の基本的な使い方

まずは、React公式ドキュメントに近い考え方で、Server ComponentからPromiseを渡し、Client Component側でuseを使って値を読み取る例を見てみましょう。

1. Server ComponentでPromiseを作成する

import { Suspense } from 'react';
import { Post } from './Post';

async function fetchPost() {
  const response = await fetch(
    'https://jsonplaceholder.typicode.com/posts/1'
  );

  if (!response.ok) {
    throw new Error('記事データの取得に失敗しました');
  }

  return response.json();
}

export default function Page() {
  const postPromise = fetchPost();

  return (
    <Suspense fallback={<p>記事を読み込み中です...</p>}>
      <Post postPromise={postPromise} />
    </Suspense>
  );
}

この例では、Server Component側でfetchPost()を呼び出し、そのPromiseをPostコンポーネントへ渡しています。Suspenseで囲んでいるため、Promiseの解決を待っている間はfallbackに指定したローディング表示が使われます。

2. Client Componentでuseを使ってPromiseを読み取る

'use client';

import { use } from 'react';

export function Post({ postPromise }) {
  const post = use(postPromise);

  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </article>
  );
}

Postコンポーネントでは、propsとして受け取ったpostPromiseuseに渡しています。Promiseが解決されると、その結果がpostに入り、記事タイトルや本文を表示できます。React公式ドキュメントでも、Server ComponentからClient ComponentへPromiseを渡し、Client Component側でuseを使って値を読む例が紹介されています。:contentReference[oaicite:7]{index=7}

古い書き方として注意したい例

次のように、Client Componentのレンダー中に直接Promiseを作成してuseへ渡す書き方は避けましょう。

function App() {
  const data = use(fetchData());

  return (
    <div>
      <h1>{data.title}</h1>
    </div>
  );
}

React 19の公式ブログでは、レンダー中に作成されたPromiseをuseに渡すことはサポート対象外であり、キャッシュ対応のSuspenseライブラリやフレームワークから渡されたPromiseを使う必要があると説明されています。:contentReference[oaicite:8]{index=8}

useフックをSuspenseと組み合わせる理由

useでPromiseを読み取る場合、データがまだ取得できていない間、Reactはそのコンポーネントのレンダーを一時停止します。このとき、近くにSuspenseがあると、fallbackに指定したUIが表示されます。

import { Suspense } from 'react';
import { UserProfile } from './UserProfile';

export default function Page() {
  const userPromise = fetch(
    'https://jsonplaceholder.typicode.com/users/1'
  ).then((response) => response.json());

  return (
    <Suspense
      fallback={<div>ユーザー情報を読み込み中です...</div>}
    >
      <UserProfile userPromise={userPromise} />
    </Suspense>
  );
}
'use client';

import { use } from 'react';

export function UserProfile({ userPromise }) {
  const user = use(userPromise);

  return (
    <section>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </section>
  );
}

このように書くことで、データ取得中のローディング表示と、取得後の画面表示を分けて管理できます。useとSuspenseを組み合わせることで、非同期データを扱うコンポーネントの見通しが良くなります。

Contextをuseで読み取る例

useはPromiseだけでなくContextにも使えます。特に、条件分岐の中でContextを読み取りたい場合に便利です。

import { createContext, use } from 'react';

const ThemeContext = createContext('light');

function Button({ show }) {
  if (!show) {
    return null;
  }

  const theme = use(ThemeContext);

  return (
    <button className={`button-${theme}`}>
      ボタン
    </button>
  );
}

export default function App() {
  return (
    <ThemeContext value="dark">
      <Button show={true} />
    </ThemeContext>
  );
}

useContextは通常、コンポーネントのトップレベルで呼び出す必要があります。一方、useは条件分岐の中でも呼び出せるため、早期returnのあとにContextを読み取りたい場面でも使いやすくなっています。:contentReference[oaicite:9]{index=9}

useフック(use API)の制約と注意点

コンポーネントまたはカスタムHookの中で呼び出す

useは通常の関数やイベントハンドラの中ではなく、ReactコンポーネントまたはカスタムHookの中で呼び出す必要があります。React公式ドキュメントでも、useを呼び出す関数はコンポーネントまたはHookでなければならないと説明されています。:contentReference[oaicite:10]{index=10}

try-catchの中では呼び出さない

usetry-catchの中では呼び出せません。Promiseの失敗を扱いたい場合は、Error Boundaryで囲むか、Promise側でcatchを使って代替値を返す方法を使います。:contentReference[oaicite:11]{index=11}

Server Componentではasync/awaitも有力な選択肢

Server Componentでデータ取得を行う場合、React公式ドキュメントではuseよりもasync/awaitを優先することが推奨されています。async/awaitawaitした位置からレンダーを再開できるため、Server Componentではより自然に扱える場面が多いです。:contentReference[oaicite:12]{index=12}

Client Componentでは安定したPromiseを渡す

Client Componentでuseを使う場合は、Client Component内でPromiseを毎回作るのではなく、Server ComponentやSuspense対応のライブラリ、フレームワークから渡された安定したPromiseを使うのが基本です。Promiseが再レンダーごとに作り直されると、意図しない再取得や警告につながる可能性があります。:contentReference[oaicite:13]{index=13}

useEffect・useStateとの違い

useEffectuseStateは、クライアント側で副作用や状態を管理するためによく使われます。たとえばブラウザAPIとの連携、イベント後のデータ取得、クライアントだけで完結する処理には今でも有効です。一方で、データ取得をuseEffectだけで行うと、ローディング状態、エラー状態、キャッシュ、重複リクエスト対策などを自分で管理する必要が出てきます。React公式ドキュメントでも、Effectはクライアントでのみ実行され、データ取得をEffectに直接書く方法にはいくつかの欠点があると説明されています。:contentReference[oaicite:14]{index=14}

比較項目useuseEffect + useState
主な用途PromiseやContextの値をレンダー中に読む副作用やクライアント状態を管理する
ローディング表示Suspenseと連携isLoadingなどを手動で管理
エラー処理Error BoundaryやPromise.catchを使うtry-catchやstateで管理することが多い
向いている場面Server ComponentsやSuspense前提のデータ読み取りブラウザAPI、イベント処理、クライアント専用処理

useフック(use API)のメリット

  • Promiseの結果をコンポーネント内で自然に扱える
  • Suspenseと組み合わせてローディングUIを整理できる
  • Server ComponentsとClient Componentsの連携がしやすい
  • Contextを条件分岐の中でも読み取れる
  • useEffectuseStateだけに頼るより、データ取得の見通しが良くなる場合がある

よくある質問

useはReact 19.2でも使えますか?

はい。useはReact 19で追加されたAPIで、React 19.2時点の公式ドキュメントにも掲載されています。:contentReference[oaicite:15]{index=15}

useはHookですか?

名前はHookのように見えますが、React公式ではuseを「React API」として説明しています。ただし、コンポーネントやカスタムHookの中で呼び出す必要がある点はHookに近いルールを持っています。

useはClient Componentで使えますか?

使えます。ただし、Client Component内でPromiseを毎回新しく作るのではなく、Server ComponentやSuspense対応ライブラリから渡された安定したPromiseを使うのが推奨されています。:contentReference[oaicite:16]{index=16}

useを使う場合、Suspenseは必須ですか?

Promiseをuseで読み取る場合、Suspenseと組み合わせるのが基本です。Promiseが未解決の間、Suspenseのfallbackが表示されます。:contentReference[oaicite:17]{index=17}

useEffectはもう不要になりますか?

不要にはなりません。useEffectは外部システムとの同期、ブラウザAPIの利用、イベント後の処理などで引き続き使われます。useは主にPromiseやContextなどの値をレンダー中に読み取るためのAPIです。

useでエラーが起きた場合はどう処理しますか?

Promiseがrejectされた場合は、近くのError Boundaryでエラー表示を行うか、Promiseのcatchで代替値を返す方法があります。use自体をtry-catchの中で呼び出すことはできません。:contentReference[oaicite:18]{index=18}

まとめ

React 19で追加されたuseは、PromiseやContextをレンダー中に読み取れる便利なAPIです。特にSuspenseやServer Componentsと組み合わせることで、非同期データの読み込みをよりシンプルに扱えます。

ただし、古いサンプルで見かけるようなuse(fetchData())という書き方には注意が必要です。現在のReactでは、Client Componentのレンダー中にPromiseを新しく作るのではなく、Server ComponentやSuspense対応の仕組みから渡された安定したPromiseを使う設計が推奨されています。

クライアントだけで完結する処理では、従来どおりuseEffectuseStateが適している場面もあります。一方で、React 19以降のServer ComponentsやSuspenseを活用するアプリケーションでは、useを理解しておくことで、より読みやすく効率的な実装がしやすくなります。

React

Posted by devsakaso