8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

v-show とどう違う? React <Activity> の魅力

Last updated at Posted at 2025-10-07

はじめに

「既視感がある」「vue の v-show みたいだ」と話題になっている <Activity> ですが、
「そんな単純な機能を今更実装するのか?」と疑問に思いました。
調べてみると、基本的な使い方は似ていても 副作用の扱いや SSR 最適化など、設計思想がまるで違うことが分かりました。
この記事では、その違いを整理して皆さんにお伝えしていきます。

<Activity> の基本挙動

コード例:表示/非表示の切り替え

// 従来の実装例
{isOpen && <Sidebar />}

// Activityを使用した実装例
<Activity mode={isOpen ? "visible" : "hidden"}>
  <Sidebar /> {/* hiddenの場合、Sidebarが非表示に */}
</Activity>

<Activity>mode="hidden"の場合に、内部で display: none を付与して DOMを非表示にしています。

付加価値となる機能

1. 状態保持と高速な復元

従来の条件付レンダリングでは、要素を非表示にした時点でアンマウントされ、再表示時に初期化処理が毎回走ります。

これに対し、<Activity> を使うと、非表示の間も状態と DOM を保持できるため、メニューの開閉などの UI 状態が維持され、再表示もスムーズに行えます。

タイトルなし.gif

2. 事前レンダリング

mode="hidden" の要素も、最初のレンダリングで裏側では低優先度で描画されます。

  • ユーザーが切り替えた瞬間に即座に表示可能
  • Suspense 対応のデータフェッチやコード分割と相性が良い
    • タブ UI で、裏タブのデータを先に取得しておくことでローディングを減らせる

3. SSR × セレクティブハイドレーション

セレクティブハイドレーションとは、SSRしたHTMLに対して、必要なコンポーネントから順に選択的にハイドレーションを進める仕組みを指します。
簡単に言うと、<Activity> を境界として区切ることで、「軽いUI → 重いUI」の順に処理されるよう制御できます。

具体例として、次のようにタブを持つ画面で考えてみましょう

function Page() {
  const [activeTab, setActiveTab] = useState('home');

  return (
    <>
      <TabButton onClick={() => setActiveTab('home')}>
        Home
      </TabButton>
      <TabButton onClick={() => setActiveTab('video')}>
        Video
      </TabButton>

      <Activity mode={activeTab === 'home' ? 'visible' : 'hidden'}>
        <Home />
      </Activity>
      <Activity mode={activeTab === 'video' ? 'visible' : 'hidden'}>
        <Video />
      </Activity>
    </>
  )
}

通常、Reactはページ全体を一度にハイドレートする必要があるため、Home または Video のレンダリングが遅い場合、ハイドレート処理中にタブボタンが反応しなくなる可能性があります。
この問題は、 <Activity> 境界として用いることで、Home/Video のハイドレーションの優先度を下げ、タブボタンを先にハイドレートして応答性を確保する形で回避できます。

ここで重要な点は、条件付レンダリングを使用しない場合でも有効 だということです。

function Page() {
  return (
    <>
      <Post />

      <Activity>
        <Comments />
      </Activity>
    </>
  );
}

常時表示の領域でも、<Activity> で囲むだけで「この塊は分離してハイドレート可能」というヒントになり、ページロード中の操作の体感速度が上がります。

v-show と <Activity> の比較

上記を踏まえて、Vue の v-show と React の <Activity> の機能を対比してみます。

項目 Vue v-show React <Activity>
DOM の扱い display: none を付与 display: none を付与
状態保持 保持する 保持する
副作用の扱い 非表示でも実行される(ライフサイクルに依存) 非表示の場合は停止する
事前レンダリング なし hidden 状態でも低優先度レンダリング(表示前に準備可能)
SSR 最適化 なし セレクティブハイドレーションで段階的に処理可能

いつ使うべきか?

  • タブ UI / モーダル / 折りたたみ
    • 状態を保持したい場面に有効
  • 裏で次に表示しそうなコンテンツを事前に準備したい場合
    • Suspense と組み合わせて「データ取得」を先行
    • ( mode="hidden"は 副作用が停止される点に注意 )
  • 一部コンポーネントが重く、初期操作の応答性を守りたい場合
    • ハイドレーションやレンダリングの優先度を下げる

まとめ

  • <Activity> は「表示切替」+「副作用の休止/再開」+「ハイドレーション分割(Selective Hydration 参加)」の3点で価値がある
  • hidden 初期化は「次に見えそうなUI」を先回りで温める強力な手段
  • SSR の見た目はそのままに、体感速度(最初に触るUIの反応性)を大きく改善できる

<Activity>は使い方こそシンプルですが、v-show の単なる表示制御とは異なり、状態保持・副作用制御・ハイドレーション最適化まで担う仕組みでした。
今後のフロントエンド最適化の定番手段になる可能性が高いので、ユースケースを見極めつつ積極的に活用していきましょう!

8
4
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
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?