SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

フロントエンド開発における定番ライブラリ「React」の最新バージョン解説

React 19.2新機能ガイド──Activity/useEffectEventを軸に見るパフォーマンス改善の新機能

フロントエンド開発における定番ライブラリ「React」の最新バージョン解説 第6回


<Activity>:UIの表示制御におけるUXとパフォーマンスの改善

 <Activity>は、React 19.2で導入された新しいコンポーネントで、従来の条件付きレンダリングやCSSのdisplayプロパティを使用した表示制御の課題を解決します。

 <Activity>のAPIは非常にシンプルで、表示・非表示に合わせて、modeプロパティを"visible""hidden"のいずれかに設定するだけです。これで子コンポーネントの表示状態が制御できます。modeプロパティが、boolean値ではなく"visible"または"hidden"の文字列を取るという仕様に、今後の拡張性が感じられます。

[リスト1]<Activity>の基本的な使い方
<Activity mode={isVisible ? "visible" : "hidden"}>
  <MyComponent />
</Activity>

<Activity>の振る舞い

 では<Activity>modeプロパティに応じてどのように振る舞うのかを見ていきましょう。以下、useEffectで実行される副作用処理をEffectと呼びます。

  • mode="visible"のとき: 通常通りレンダリングし、UI を表示してEffectを実行
  • mode="hidden"のとき: UIはdisplay:none !importantで非表示にしつつ、State/DOMは維持し、Effectはクリーンアップ

 この振る舞いが条件付きレンダリングや単なるdisplay: noneとは異なる挙動を生み出します。

従来の方法と<Activity>の挙動の違い

 実際にサンプルコードを使って、CSSのdisplayプロパティを使用した表示制御、従来の条件付きレンダリング、そして<Activity>を使った表示制御の違いを見てみましょう。

 まず、リスト2の通り入力コンポーネントを用意します。

[リスト2]入力フォームコンポーネント ※ファイル名:samples/01/src/index.jsx
function MyForm({ formId }) {
  const [name, setName] = useState("");

  useEffect(() => {
    console.log(`mounted: ${formId}`);
    return () => {
      console.log(`cleanup: ${formId}`);
    };
  }, []);

  return (
    <div style={{ border: "1px solid silver", margin: "0.5em", padding: "0.5em" }}>
      <label>
        名前: <input value={name} onChange={(e) => setName(e.target.value)} />
      </label>
    </div>
  );
}

 次にリスト3は、3つの方法でフォームコンポーネントを表示・非表示に切り替える例です。

[リスト3]<Activity>による表示制御の例 ※ファイル名: samples/01/src/index.jsx
// (1) 条件付き表示制御 (display プロパティ)
<div style={{ display: isVisible ? "block" : "none" }}>
  <MyForm formId="1. 条件付き表示制御" />
</div>
// (2) 条件付きレンダリング
{isVisible && <MyForm formId="2. 条件付きレンダリング" />}
// (3) Activity
<Activity mode={isVisible ? "visible" : "hidden"}>
  <MyForm formId="3. Activity" />
</Activity>

 図2はサンプルコード01を実行した画面例です。ロードされた時点で、Consoleログに "mounted: 1. 条件付き表示制御" と表示されており、すでに(1)のEffectが実行されていることがわかります。

 一方、(2)と(3)ではまだEffectは実行されていません。

図2:サンプルコード (<Activity>) の実行例
図2:サンプルコード(<Activity>)の実行例

 次に「表示」ボタンをクリックしてフォームを表示させると、図3のように(2)と(3)のEffectが実行され、Consoleログに "mounted: ~" が表示されます。

図3:サンプルコード (<Activity>) の実行例
図3:サンプルコード () の実行例

 ここで「非表示」ボタンをクリックしてフォームを再度非表示にすると、図4のように(2)と(3)は副作用のクリーンアップ処理が実行(Consoleログに "cleanup" が表示)されます。

 ただし、(2)ではDOMから完全に消えてしまっているのに対し、<Activity>を使った(3)は非表示になるだけでDOMに要素が残っていることがポイントです。

図4:サンプルコード (<Activity>) の実行例
図4:サンプルコード () の実行例

 さらに図5のように「表示」状態で、各テキストボックスに文字列を入力してから「非表示」ボタンをクリックしてみましょう。

図5:<Activity> では非表示でもstateやDOMが維持される
図5:<Activity>では非表示でもstateやDOMが維持される

 (2)の条件付きレンダリングではコンポーネントがアンマウントされるため、state(=入力した文字列)は失われます。一方、<Activity>を使った(3)は非表示になるものの、stateやDOMが維持されており、再度「表示」ボタンをクリックすると、入力した文字列が保持されていることがわかります。

<Activity>のメリットとユースケース

 ここまで見てきたように、<Activity>の特徴は「非表示時にアンマウントせず、stateやDOMを保持して、Effectのみクリーンアップする」点にあります。非表示のときに無駄な処理を抑制しつつ、再表示時に状態を復元できることで、UXの向上やパフォーマンス改善が期待できます。

 そのほかにも以下のメリットがあります。

  1. プリレンダリング(先読み):hiddenモードであっても子コンポーネントをレンダリングできる(Effectは実行されない) → データ取得、コード読み込み、画像ロードを先に進めておくことで、表示切り替え時の遅延を軽減できる。
  2. 優先度制御:hidden領域のレンダリング更新は優先度を下げて実行されるよう制御されるため、ユーザーに見えているUIに対する応答性を優先できる。
  3. 切り替え時のアニメーション制御:ActivityはViewTransitionと併用したトランジション動作をサポートしており、表示/非表示の切り替え時にenter/exitアニメーションを発生させる制御も可能。

 いずれもパフォーマンスやUXの向上に寄与する重要なポイントです。ただしプリレンダリングについては、Suspenseとの組み合わせが必要になり、useEffect内のデータ取得は先読みでは実行されない点に注意が必要です。

 <Activity>はタブUIやサイドバーなど表示・非表示を切り替えることが前提のコンポーネントで特に有効です。状態保持が求められるフォームや設定画面、ダッシュボードなどでの利用が考えられます。

 すべてを<Activity>に置き換える必要はなく、従来の手法を使っている部分で<Activity>に置き換えられそうな場所から段階的に導入していくのがよいでしょう。

次のページ
useEffectEvent:Effect内イベントハンドラーと依存関係の分離

この記事は参考になりましたか?

フロントエンド開発における定番ライブラリ「React」の最新バージョン解説連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 山田 研二(ヤマダ ケンジ)

株式会社MSEN CTO。高校卒業後、大阪大学の研究所で働きながらプログラミングやWebデザインをはじめ、以後20年以上、Webサイト制作や業務システムの構築を手がけています。フリーソフトもいくつか公開しています。好きな言語はC#とTypeScript、趣味は旅行です。 GitHub アカウント WINGSプロジェクト について>有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での 登録メンバ は約50名で、現在も執筆メンバを 募集中 。興味のある方は、どしどし応募頂きたい。 著書 記事 多数。 RSS X: @WingsPro_info (公式)、 @WingsPro_info/wings (メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/22484 2025/11/14 18:28

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー