React.Suspenseは、 v16.6で導入されたReact.lazy()とともに、コンポーネントが実際にレンダリングする前に何かを待機できるようにする新しい機能を追加します。 この新しい機能により、コードの分割とReactコンポーネントの遅延読み込みが簡単になります。

入門

開始するには、Reactv16.6以降を使用していることを確認する必要があります。 新しいプロジェクトを開始する場合、または正しいバージョンではない古いプロジェクトで作業している場合は、次のようにします。

# Via npm
$ npm install --save react react-dom

# Or via Yarn
$ yarn add react react-dom

次に、他のコンポーネントの遅延読み込みを処理するコンポーネント内で、Suspenselazyの両方をインポートします。

import React, { lazy, Suspense } from 'react';

コード分割について

Suspenselazyを使用すると、コンポーネントをすばやく簡単に遅延ロードできますが、アプリケーション全体を1つにまとめる場合、ゲートから多くのメリットが得られない可能性があることを指摘しておく価値があります。 Webpackのようなスクリプト。

この記事の範囲外ですが、WebpackドキュメントでWebpackを使用したコード分割について読むことができます。

React.lazy()

lazy()メソッドは、次のように、別のコンポーネントをimportすることが期待される最初のパラメーターとして関数を取ります。

const SomeComponent = lazy(() => import('./SomeComponent');

importは、lazy()に渡された関数の内部にあるため、コンポーネントのロードは、上部にある他のインポートで熱心にロードされるのではなく、実際にコンポーネントを使用するまで行われません。あなたのファイルの。

React.Suspense

React.Suspenseコンポーネントを使用すると、コンポーネントをラップして、ラップされたコンポーネントのロード中に表示されるfallbackコンポーネントを指定できます。

<Suspense fallback={<div>Loading...</div>}>
  <SomeComponent />
</Suspense>

これは、大きい側にあるコンポーネント、またはimportの大きいライブラリ(react-pdfreact-draft-wysiwygなど)に発生するコンポーネントをロードする場合に特に役立ちます。

コンポーネントが大規模な部門に属していない場合でも、遅延読み込みは、最良のインターネット接続を持たない可能性のあるエンドユーザーを支援することができます。

すべてを一緒に入れて

React.SuspenseReact.lazy()の使用感を実際に得るには、2つの別々のファイルが必要になります。 1つは基本的なReactアプリの定型文であり、もう1つは遅延読み込みされるコンポーネントです。

importに行くコンポーネントから始めましょう。 この例では、常にdapper Alligator.ioロゴをロードする非常に単純なコンポーネントを作成しました。

AlligatorioLogo.jsx
import React from "react";

function AlligatorioLogo() {
  const imageSource = "https://uploads.codesandbox.io/uploads/user"
    + "/39d6d9f6-60d2-4a60-9eb7-9250c3417bef"
    + "/saY6-alligatorio-logo.png";

  return (
    <img
      alt="Alligator.io Logo"
      src={imageSource}
      width="250"
    />
  );
}

export default AlligatorioLogo;

次は、アプリのボイラープレートコードと、コンポーネントの読み込みを手動でトリガーできるようにするための状態ロジックの一部です。

App.jsx
import React, { Component, Fragment, lazy, Suspense } from "react";
import { render } from "react-dom";

import "./styles.css";

const AlligatorioLogo = lazy(() => import("./AlligatorioLogo"));

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      showLogo: false
    };
  }

  onClick = () => {
    this.setState({ showLogo: !this.state.showLogo });
  };

  render() {
    return (
      <div className="App">
        <h1>React.lazy() + &lt;React.Suspense /&gt; Demo</h1>
        <div>
          <button onClick={this.onClick}>
            {this.state.showLogo &&
              <Fragment>Click to Hide the Logo</Fragment>
            }
            {!this.state.showLogo && (
              <Fragment>Click to Show the Logo</Fragment>
            )}
          </button>
        </div>
        <hr />
        {this.state.showLogo && (
          <Suspense fallback={<div>Loading...</div>}>
            <AlligatorioLogo />
          </Suspense>
        )}
      </div>
    );
  }
}

const container = document.createElement("div");
document.body.appendChild(container);
render(<App />, container);

ご覧のとおり、Suspenselazy()を使用することはあまりありません。 非常に単純であるため、既存のシステムをシステムに移植することは、特にコンポーネントを個別のファイルに既に分割している場合は、それほど大きな負担にはなりません。

結論

React.lazy()React.Suspenseの導入は、最新のWebアプリケーションを構築するために作成する必要のある定型コードの量を減らすのに役立つ素晴らしい一歩です。

Suspenseはすでに非常に強力ですが、欠点がないわけではありません。 将来のv16ポイントリリースのReactロードマップにある大きな欠けている部分は、データフェッチでSuspenseを使用する機能です。

このデータフェッチ機能が利用可能になると、SuspenseはAJAX呼び出しなどを待機し、ロード中にフォールバックコンポーネントを表示できるようになります。

Suspenseは、サーバー側のレンダリングで使用する準備が整っていないことにも注意してください。

React.SuspenseReact.lazy()を試してみる準備ができたら、 CodeSandbox にアクセスして、この記事のコードの動作を確認してください。