私は 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);
});
}
}