SHOEISHA iD

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

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

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

フロントエンド開発の定番「React」バージョン18の新機能を解説──並行レンダーで操作感が向上!

  • X ポスト
  • このエントリーをはてなブックマークに追加

コンポーネント表示までの一時表示を指定できるSuspense

 Suspenseは、コンポーネントの表示までに時間がかかる時の「ロード中」状態を指定できる機能です。親コンポーネントの表示後、5秒経過後に子コンポーネントが表示される図11のサンプルで説明します。

図11 Suspenseのサンプル(p006-suspense-csr)
図11 Suspenseのサンプル(p006-suspense-csr)

 Suspenseを指定するには、リスト10の通り記述します。(1)の部分がSuspenseで、fallback属性にロード中の表示を指定した<Suspense>要素で、Subコンポーネント(<Sub />)を囲みます。

[リスト10]Suspenseを指定する実装(p006-suspense-csr/src/App.js)
return (
  <div style={{backgroundColor: 'lightpink'}}>
    <h3>React 18 Suspense</h3>
    <div>ここは親コンポーネントです</div>
    {/* ここにSuspenseを指定してSubコンポーネントを配置 ...(1)*/}
    <Suspense fallback={<div>ロード中です...</div>}>
      <Sub />
    </Suspense>
  </div>
);

 Subコンポーネントの記述はリスト11の通りです。

[リスト11]Subコンポーネント(p006-suspense-csr/src/Sub.js)
let isLoaded = false; // ロード中を表す変数 ...(1)
function Sub() {
  // ロード済みの場合→コンポーネントの表示内容をJSXで記述して返却 ...(2)
  if (isLoaded) {
    isLoaded = false; // 次の表示に備えてフラグを戻す
    return (
      <div style={{backgroundColor: 'lightgreen'}}>
        <h4>子コンポーネント</h4>
        <div>ロード完了!</div>
      </div>
    );
  }
  // ロード中の場合→5秒後に終了するPromiseをthrow ...(3)
  else {
    throw new Promise(resolve => {
      setTimeout(() => {
        isLoaded = true;
        resolve();
      }, 5000)
    });
  }
}

 ロード中を表す変数isLoadedをfalseで初期化します(1)。コンポーネントの記述では、ロード済みの場合(2)はコンポーネントの表示内容を返却し、ロード中の場合(3)は、5秒後に成功するPromiseをthrowするようにします。

ReactのSSR機能とSuspense

 React 18ではSSR機能を利用時に、Suspenseに対応してHTMLをストリーム出力するrenderToPipeableStream(Node.js用)、renderToReadableStream(DenoなどのWeb Stream用)が利用できるようになりました。本記事ではrenderToPipeableStreamの例を紹介します。

[リスト12]SSRにおけるHTMLストリーム処理(p007-suspense-ssr/server/index.js)
//HTML要素をJSXで記述 ...(1)
const htmlElem =(略);
// HTMLをストリームするように記述 ...(2)
const { pipe } = ReactDOMServer.renderToPipeableStream(
  htmlElem,
  {
    // ハイドレーションを行うJavaScriptファイル ...(3)
    bootstrapScripts: ['/index.js'],
    // ストリームの処理 ...(4)
    onShellReady() {
      res.setHeader('content-type', 'text/html');
      pipe(res);
    }
  }
);

 (1)で記述したHTML要素を、(2)のrenderToPipeableStream関数の第1要素に指定します。第2引数のJavaScriptオブジェクトには、(3)でハイドレーションを行うJavaScriptファイルを指定し、(4)にはWebブラウザーにコンテンツをストリームする処理を記述します。この処理により、Suspenseを含むWebページは、まずSuspense中の内容がHTMLとしてダウンロードされますが、HTTPの接続はここで切断されず、Suspense終了後に、新しい表示内容と、表示を更新するJavaScriptが追加でダウンロードされます。

図12 SSRでのSuspenseを含むWebページのソースコードをPostmanで表示(p007-suspense-ssr)
図12 SSRでのSuspenseを含むWebページのソースコードをPostmanで表示(p007-suspense-ssr)

まとめ

 本記事では、React 18の新機能について説明しました。前半となる今回は、新機能のベースになる並行レンダリングと、バッチング、TransitionやDeferredValue、Suspense、およびサーバーサイドレンダリングについて説明しました。

 次回は、潜在的な問題点を洗い出すStrictモードへの機能追加や、新たなフックについて紹介します。

参考資料

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
フロントエンド開発における定番ライブラリ「React」の最新バージョン解説連載記事一覧
この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/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本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/17953 2023/07/06 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング