0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

useTransitionフックでUXを改善する非同期UIの設計

Last updated at Posted at 2025-07-31

React 18から導入されたuseTransitionフックは、UIの応答性を保ちながら非同期処理を扱える強力なツールです。
検索フォームやフィルター機能など、重たい再レンダリングが発生する場面で特に効果を発揮します。

この記事では、useTransitionを使ったUIパフォーマンス最適化の手法と、従来の状態管理との違いを実際のコードで紹介します。

useTransitionとは?

useTransitionフックを使うと、状態の更新に優先順位をつけることができます。これにより、UIの即時反応(クリック、入力など)は保ちつつ、重い処理は「低優先」で遅れて実行されるようになります。

const [isPending, startTransition] = useTransition();

isPending: 非同期状態のフラグ。UI側でスピナーなどを制御するのに使います。
startTransition(callback): 指定した更新処理を低優先としてスケジュールします。

従来の実装(useStateのみ)

以下のように検索ボックスに入力するたびにsetSearchResults()を呼び出すと、検索結果の描画に時間がかかるとUIが固まることがあります。

import { useState } from "react";

function SearchComponent({ searchData }: { searchData: string[] }) {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState<string[]>([]);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setQuery(value);
    const filtered = searchData.filter((item) => item.includes(value));
    setResults(filtered);
  };

  return (
    <div>
      <input value={query} onChange={handleChange} placeholder="検索" />
      <ul>
        {results.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

useTransitionを使った改善

以下のようにstartTransitionを使うことで、重たいsetResults()を低優先度にして、UIの応答性を保つことができます。

import { useState, useTransition } from "react";

function SearchComponent({ searchData }: { searchData: string[] }) {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState<string[]>([]);
  const [isPending, startTransition] = useTransition();

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setQuery(value);

    startTransition(() => {
      const filtered = searchData.filter((item) => item.includes(value));
      setResults(filtered);
    });
  };

  return (
    <div>
      <input value={query} onChange={handleChange} placeholder="検索" />
      {isPending && <p>読み込み中...</p>}
      <ul>
        {results.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

主な改善点

応答性の向上:重いレンダリングが入力応答を妨げなくなる。UX向上。
保留状態の表示isPending で「読み込み中」などのUIが制御できる。
コードの明確化:非同期・低優先の処理が明確に分離されて読みやすくなる。

まとめ

useTransitionは、ReactアプリのパフォーマンスとUXを改善する非常に効果的な手段です。特に以下のような場面での導入をおすすめします:
・フィルターや検索などの再描画が重い処理
・クライアント側でデータを大量に扱うページ
・入力やクリック応答がカクついている箇所
React 18以降を利用しているプロジェクトでは、ぜひ一度useTransitionを取り入れてみてください。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?