React を使用してマルチページ アプリを構築するにはどうすればよいでしょうか? 質問する

React を使用してマルチページ アプリを構築するにはどうすればよいでしょうか? 質問する

私は NodeJS でアプリを構築しており、アプリケーション全体のインタラクティブ コンポーネントの一部に React を使用したいと考えています。シングル ページ アプリにしたくありません。

複数ページのアプリ全体で React コンポーネントを分割またはバンドルするにはどうすればよいですか?

現在、すべてのコンポーネントは 1 つのファイルに含まれていますが、アプリの一部のセクションではそれらをロードしない可能性があります。

これまでのところ、React がレンダリングするコンテナの ID を検索して、条件文を使用してコンポーネントをレンダリングしようとしています。React のベスト プラクティスが何であるかは 100% 確信していません。次のようになります。

if(document.getElementById('a-compenent-in-page-1')) {
    React.render(
        <AnimalBox url="/api/birds" />,
        document.getElementById('a-compenent-in-page-1')
    );
}
    
if(document.getElementById('a-compenent-in-page-2')) {
    React.render(
        <AnimalBox url="/api/cats" />,
        document.getElementById('a-compenent-in-page-2')
    );
}

if(document.getElementById('a-compenent-in-page-3')) {
    React.render(
        <AnimalSearchBox url="/api/search/:term" />,
        document.getElementById('a-compenent-in-page-3')
    );
}

まだドキュメントを読んでいるところですが、マルチページ アプリに必要なものがまだ見つかっていません。

ベストアンサー1

現在、私は同様のことをやっています。

このアプリケーションは完全な React アプリではありません。私は、独立した CommentBox などの動的な機能に React を使用しています。また、特別なパラメータを使用して任意の時点で含めることができます。

ただし、すべてのサブアプリが 1 つのファイルに読み込まれて組み込まれるall.jsため、ページ間でブラウザによってキャッシュされる可能性があります。

SSR テンプレートにアプリを含める必要がある場合は、クラス "__react-root" と特別な ID (レンダリングする React アプリの名前) を持つ DIV を含めるだけです。

ロジックは実にシンプルです。

import CommentBox from './apps/CommentBox';
import OtherApp from './apps/OtherApp';

const APPS = {
  CommentBox,
  OtherApp
};

function renderAppInElement(el) {
  var App = APPS[el.id];
  if (!App) return;

  // get props from elements data attribute, like the post_id
  const props = Object.assign({}, el.dataset);

  ReactDOM.render(<App {...props} />, el);
}

document
  .querySelectorAll('.__react-root')
  .forEach(renderAppInElement)

<div>Some Article</div>
<div id="CommentBox" data-post_id="10" class="__react-root"></div>

<script src="/all.js"></script>

編集

webpack はコード分割と LazyLoading を完全にサポートしているので、すべてのアプリを 1 つのバンドルでロードする必要はなく、分割してオンデマンドでロードする例を含めるのが合理的だと思いました。

import React from 'react';
import ReactDOM from 'react-dom';

const apps = {
  'One': () => import('./One'),
  'Two': () => import('./Two'),
}

const renderAppInElement = (el) => {
  if (apps[el.id])  {
    apps[el.id]().then((App) => {
      ReactDOM.render(<App {...el.dataset} />, el);
    });
  }
}

おすすめ記事