renderToString
renderToString
は React ツリーを HTML 文字列にレンダーします。
const html = renderToString(reactNode, options?)
リファレンス
renderToString(reactNode, options?)
サーバ上において、renderToString
を呼び出してあなたのアプリを HTML にレンダーします。
import { renderToString } from 'react-dom/server';
const html = renderToString(<App />);
クライアント側では、このようにサーバ生成された HTML を操作可能にするために hydrateRoot
を用います。
引数
-
reactNode
: HTML にレンダーしたい React ノード。例えば、<App />
のような JSX ノード。 -
省略可能
options
: サーバレンダー用のオプションが含まれたオブジェクト。- 省略可能
identifierPrefix
: React がuseId
によって生成する ID に使用する文字列プレフィックス。同じページ上に複数のルートを使用する際に、競合を避けるために用います。hydrateRoot
にも同じプレフィックスを渡す必要があります。
- 省略可能
返り値
HTML 文字列。
注意点
-
renderToString
のサスペンスに対するサポートは限定的です。コンポーネントがサスペンドすると、renderToString
はそのフォールバックを HTML として直ちに送信します。 -
renderToString
はブラウザでも動作しますが、クライアントコードでの使用は推奨されません。
使用法
React ツリーを HTML として文字列にレンダーする
renderToString
を呼び出して、あなたのアプリを、サーバからのレスポンスとして送信できる HTML 文字列にレンダーします。
import { renderToString } from 'react-dom/server';
// The route handler syntax depends on your backend framework
app.use('/', (request, response) => {
const html = renderToString(<App />);
response.send(html);
});
これにより、React コンポーネントの初期の非インタラクティブな HTML 出力が生成されます。クライアント側では、サーバーが生成した HTML のハイドレーションを行い操作可能にするために、hydrateRoot
を呼び出す必要があります。
代替手段
サーバ上で renderToString
からストリーム対応メソッドへの移行
renderToString
は直ちに文字列を返すため、ストリーミングやデータの待機をサポートしていません。
可能な場合、全機能を備えた以下の代替手段の使用を推奨します。
- Node.js を使用している場合は、
renderToPipeableStream
を使用します。 - Deno や、Web Stream をサポートするモダンなエッジランタイムを使用している場合は、
renderToReadableStream
を使用します。
サーバ環境がストリームをサポートしていない場合は、renderToString
の使用を続けても構いません。
クライアントコードから renderToString
を削除する
時に、renderToString
はクライアント上で何らかのコンポーネントを HTML に変換するために使用されることがあります。
// 🚩 Unnecessary: using renderToString on the client
import { renderToString } from 'react-dom/server';
const html = renderToString(<MyIcon />);
console.log(html); // For example, "<svg>...</svg>"
クライアント上で react-dom/server
をインポートすることは、不必要にバンドルサイズが増加するため避けるべきです。ブラウザで何らかのコンポーネントを HTML にレンダーする必要がある場合は、createRoot
を使用し、DOM から HTML を読み取ります:
import { createRoot } from 'react-dom/client';
import { flushSync } from 'react-dom';
const div = document.createElement('div');
const root = createRoot(div);
flushSync(() => {
root.render(<MyIcon />);
});
console.log(div.innerHTML); // For example, "<svg>...</svg>"
flushSync
の呼び出しは、innerHTML
プロパティを読み取る前に DOM が更新されるようにするために必要です。
トラブルシューティング
コンポーネントがサスペンドすると HTML に常にフォールバックが含まれる
renderToString
はサスペンスを完全にはサポートしていません。
何らかのコンポーネントが(lazy
で定義されている、データをフェッチしているなどの理由で)サスペンドした場合、renderToString
はそのコンテンツがロードされるのを待ちません。代わりに、renderToString
はその上にある最も近い <Suspense>
バウンダリを見つけ、その fallback
を HTML にレンダーします。コンテンツは、クライアントでコードがロードされるまで表示されません。
これを解決するには、ストリーミング対応の推奨ソリューションのいずれかを使用します。これらは、サーバ上でコンテンツがロードされるにつれて分割してコンテンツをストリームするため、クライアントコードがロードされる前に、ユーザはページが徐々に埋まっていくところを見ることができます。