落とし穴

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 γ«γƒ¬γƒ³γƒ€γƒΌγ—γΎγ™γ€‚γ‚³γƒ³γƒ†γƒ³γƒ„γ―γ€γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ§γ‚³γƒΌγƒ‰γŒγƒ­γƒΌγƒ‰γ•γ‚Œγ‚‹γΎγ§θ‘¨η€Ίγ•γ‚ŒγΎγ›γ‚“γ€‚

γ“γ‚Œγ‚’θ§£ζ±Ίγ™γ‚‹γ«γ―γ€γ‚ΉγƒˆγƒͺγƒΌγƒŸγƒ³γ‚°ε―ΎεΏœοΏ½?推ε₯¨γ‚½γƒͺγƒ₯ーション�?γ„γšγ‚Œγ‹γ‚’δ½Ώη”¨γ—γΎγ™γ€‚γ“γ‚Œγ‚‰γ―γ€γ‚΅γƒΌγƒδΈŠγ§γ‚³γƒ³γƒ†γƒ³γƒ„γŒγƒ­γƒΌγƒ‰γ•γ‚Œγ‚‹γ«γ€γ‚Œγ¦εˆ†ε‰²γ—γ¦γ‚³γƒ³γƒ†γƒ³γƒ„γ‚’γ‚ΉγƒˆγƒͺγƒΌγƒ γ™γ‚‹γŸγ‚γ€γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒΌγƒ‰γŒγƒ­γƒΌγƒ‰γ•γ‚Œγ‚‹ε‰γ«γ€γƒ¦γƒΌγ‚Άγ―γƒšγƒΌγ‚ΈγŒεΎγ€…γ«εŸ‹γΎγ£γ¦γ„γγ¨γ“γ‚γ‚’θ¦‹γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚