renderToString
renderToString
์ React ํธ๋ฆฌ๋ฅผ HTML ๋ฌธ์์ด๋ก ๋ ๋๋งํฉ๋๋ค.
const html = renderToString(reactNode, options?)
๋ ํผ๋ฐ์ค
renderToString(reactNode, options?)
์๋ฒ์์ renderToString
์ ์คํํ๋ฉด ์ฑ์ HTML๋ก ๋ ๋๋งํฉ๋๋ค.
import { renderToString } from 'react-dom/server';
const html = renderToString(<App />);
ํด๋ผ์ด์ธํธ์์ hydrateRoot
๋ฅผ ํธ์ถํ๋ฉด ์๋ฒ์์ ์์ฑ๋ HTML์ ์ํธ์์ฉํ๊ฒ ๋ง๋ญ๋๋ค.
์๋ ์์๋ฅผ ์ฐธ๊ณ ํ์ธ์.
๋งค๊ฐ๋ณ์
reactNode
: HTML๋ก ๋ ๋๋งํ React ๋ ธ๋์ ๋๋ค. ์๋ฅผ ๋ค์ด<App />
๊ณผ ๊ฐ์ JSX ๋ ธ๋์ ๋๋ค.- optional
options
: ์๋ฒ ๋ ๋๋ง์ ์ํ ๊ฐ์ฒด์ ๋๋ค.- optional
identifierPrefix
:useId
์ ์ํด ์์ฑ๋ ID์ ๋ํด React๊ฐ ์ฌ์ฉํ๋ ๋ฌธ์์ด ์ ๋์ฌ์ ๋๋ค. ๊ฐ์ ํ์ด์ง์์ ์ฌ๋ฌ ๋ฃจํธ๋ฅผ ์ฌ์ฉํ ๋ ์ถฉ๋์ ํผํ๊ธฐ ์ํด ์ ์ฉํฉ๋๋ค.hydrateRoot
์ ์ ๋ฌ๋ ์ ๋์ฌ์ ๋์ผํด์ผ ํฉ๋๋ค.
- optional
๋ฐํ๊ฐ
HTML ๋ฌธ์์ด.
์ฃผ์ ์ฌํญ
-
renderToString
๋ Suspense ์ง์์ ํ๊ณ๊ฐ ์์ต๋๋ค. ์ปดํฌ๋ํธ๊ฐ ์ค๋จ๋๋ค๋ฉดrenderToString
๋ ์ฆ์ ํด๋น ํด๋ฐฑ์ HTML๋ก ๋ณด๋ ๋๋ค. -
renderToString
์ ๋ธ๋ผ์ฐ์ ์์ ๋์ํ์ง๋ง, ํด๋ผ์ด์ธํธ ์ฝ๋์์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํ์ง ์์ต๋๋ค.
์ฌ์ฉ๋ฒ
React ํธ๋ฆฌ๋ฅผ HTML ๋ฌธ์์ด๋ก ๋ ๋๋งํ๊ธฐ
์๋ฒ ์๋ต๊ณผ ํจ๊ป ๋ณด๋ผ ์ ์๋ HTML ๋ฌธ์์ด๋ก ์ฑ์ ๋ ๋๋งํ๋ ค๋ฉด renderToString
์ ํธ์ถํ์ธ์.
import { renderToString } from 'react-dom/server';
// ๋ผ์ฐํธ ํธ๋ค๋ฌ ๊ตฌ๋ฌธ์ ๋ฐฑ์๋ ํ๋ ์์ํฌ์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค
app.use('/', (request, response) => {
const html = renderToString(<App />);
response.send(html);
});
์ด๋ React ์ปดํฌ๋ํธ์ ์ด๊ธฐ ์ํธ์์ฉํ์ง ์๋ HTML ์ถ๋ ฅ์ ์์ฑํฉ๋๋ค. ํด๋ผ์ด์ธํธ์์ ์๋ฒ์์ ์์ฑ๋ HTML์ Hydrateํ์ฌ ์ํธ์์ฉํ ์ ์๋๋ก hydrateRoot
๋ฅผ ์คํํด์ผ ํฉ๋๋ค.
๋์
์๋ฒ์์ renderToString
์ ์คํธ๋ฆฌ๋ฐ ๋ ๋๋ง์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
renderToString
์ ๋ฌธ์์ด์ ์ฆ์ ๋ฐํํ๋ฏ๋ก, ๋ก๋ฉ ์ค์ธ ์ฝํ
์ธ ๋ฅผ ์คํธ๋ฆฌ๋ฐํ๋ ๊ฒ์ ์ง์ํ์ง ์์ต๋๋ค.
๊ฐ๋ฅํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์์ ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ ๋์์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
- Node.js๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
renderToPipeableStream
์ ์ฌ์ฉํ์ธ์. - Deno์ ์ต์ ์ฃ์ง ๋ฐํ์์์ Web Stream์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
renderToReadableStream
์ ์ฌ์ฉํ์ธ์.
์๋ฒ ํ๊ฒฝ์์ ์คํธ๋ฆผ์ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ์๋ renderToString
์ ๊ณ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๋ฒ์์ renderToString
์ ์ ์ ํ๋ฆฌ๋ ๋๋ก ๋ง์ด๊ทธ๋ ์ด์
renderToString
์ ๋ฌธ์์ด์ ์ฆ์ ๋ฐํํ๋ฏ๋ก, ์ ์ HTML ์์ฑ์ ์ํด ๋ฐ์ดํฐ ๋ก๋ฉ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ ์ง์ํ์ง ์์ต๋๋ค.
๊ฐ๋ฅํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์์ ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ ๋์์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
- Node.js๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
prerenderToNodeStream
์ ์ฌ์ฉํ์ธ์. - Deno์ ์ต์ ์ฃ์ง ๋ฐํ์์์ Web Streams์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
prerender
๋ฅผ ์ฌ์ฉํ์ธ์.
์ ์ ์ฌ์ดํธ ์์ฑ ํ๊ฒฝ์์ ์คํธ๋ฆผ์ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ์๋ renderToString
์ ๊ณ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํด๋ผ์ด์ธํธ ์ฝ๋์์ renderToString
์ ๊ฑฐํ๊ธฐ
ํด๋ผ์ด์ธํธ์์ ์ผ๋ถ ์ปดํฌ๋ํธ๋ฅผ HTML๋ก ๋ณํํ๊ธฐ ์ํด renderToString
์ ์ฌ์ฉํ๊ธฐ๋ ํฉ๋๋ค.
// ๐ฉ ๋ถํ์: ํด๋ผ์ด์ธํธ์์ renderToString ์ฌ์ฉํ๊ธฐ
import { renderToString } from 'react-dom/server';
const html = renderToString(<MyIcon />);
console.log(html); // ์๋ฅผ ๋ค์ด, "<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); // ์๋ฅผ ๋ค์ด, "<svg>...</svg>"
flushSync
ํธ์ถ์ innerHTML
์์ฑ์ ์ฝ๊ธฐ ์ ์ DOM์ ์
๋ฐ์ดํธํ๊ธฐ ์ํด ํ์ํฉ๋๋ค.
๋ฌธ์ ํด๊ฒฐ
์ปดํฌ๋ํธ๊ฐ ์ผ์ ์ค๋จ๋๋ฉด HTML์ ํญ์ ํด๋ฐฑ์ ํฌํจํฉ๋๋ค.
renderToString
์ Suspense๋ฅผ ์๋ฒฝํ๊ฒ ์ง์ํ์ง ์์ต๋๋ค.
์ผ๋ถ ์ปดํฌ๋ํธ๊ฐ ์ผ์ ์ค๋จSuspend๋๊ฑฐ๋ (์๋ฅผ ๋ค์ด, lazy
์ ํจ๊ป ์ ์๋๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋) renderToString
์ ์ฝํ
์ธ ๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์ต๋๋ค. renderToString
๋ ๊ทธ ์์ ๊ฐ์ฅ ๊ฐ๊น์ด <Suspense>
๊ฒฝ๊ณ๋ฅผ ์ฐพ์ fallback
ํ๋กํผํฐ๋ฅผ HTML์ ๋ ๋๋งํฉ๋๋ค. ๋ด์ฉContent์ ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ๋ก๋๋ ๋๊น์ง ๋ํ๋์ง ์์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ๊ถ์ฅ๋๋ ์คํธ๋ฆฌ๋ฐ ์๋ฃจ์ ์ค ํ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์ต๋๋ค. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ๊ฒฝ์ฐ, ์๋ฒ์์ ํด๊ฒฐ๋๋ ๋๋ก ์ฝํ ์ธ ๋ฅผ ์์ ๋จ์chunk๋ก ์คํธ๋ฆฌ๋ฐํ ์ ์์ด ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ๋ก๋๋๊ธฐ ์ ์ ์ฌ์ฉ์๊ฐ ํ์ด์ง๊ฐ ๋จ๊ณ์ ์ผ๋ก ๋ํ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์ ์ ์ฌ์ดํธ ์์ฑ์ ๊ฒฝ์ฐ, ์ ์ HTML์ ์์ฑํ๊ธฐ ์ ์ ๋ชจ๋ ์ฝํ ์ธ ๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์์ต๋๋ค.