落とし穴

renderToString はストリーミングやデータ待機をサポートしていません。代替手段を見る。

renderToString は React ツリーを HTML 文字列にレンダーします。

const html = renderToString(reactNode)

リファレンス

renderToString(reactNode)

サーバ上において、renderToString を呼び出してあなたのアプリを HTML にレンダーします。

import { renderToString } from 'react-dom/server';

const html = renderToString(<App />);

クライアント側では、このようにサーバ生成された HTML を操作可能にするために hydrateRoot を用います。

さらに例を見る

引数

  • reactNode: HTML にレンダーしたい React ノード。例えば、<App /> のような JSX ノード。

返り値

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 からストリーム対応メソッドへの移行

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 にレンダーします。コンテンツは、クライアントでコードがロードされるまで表示されません。

これを解決するには、ストリーミング対応の推奨ソリューションのいずれかを使用します。これらは、サーバ上でコンテンツがロードされるにつれて分割してコンテンツをストリームするため、クライアントコードがロードされる前に、ユーザはページが徐々に埋まっていくところを見ることができます。