출처: https://react.dev/reference/react-dom/server/renderToString
Reference
renderToString(reactNode, options?)
서버에서 renderToString
을 호출하면 앱을 HTML로 렌더링할 수 있습니다.
import { renderToString } from 'react-dom/server';
const html = renderToString(<App />);
클라이언트에서는 hydrateRoot를 호출해 서버에서 생성된 HTML을 인터랙티브하게 만들 수 있습니다.
Parameters
reactNode
: HTML로 렌더링할 React 노드(예:<App />
와 같은 JSX 노드)- optional
options
: 서버 렌더 옵션 객체- optional
identifierPrefix
: useId로 생성되는 id에 사용할 prefix 문자열. 여러 React root를 한 페이지에 사용할 때 id 충돌 방지에 유용합니다. hydrateRoot에 전달한 prefix와 동일해야 합니다.
- optional
Returns
HTML 문자열을 반환합니다.
Caveats(주의사항)
renderToString
은 Suspense 지원이 제한적입니다. 컴포넌트가 suspend되면 즉시 fallback을 HTML로 렌더링합니다.- 브라우저(클라이언트)에서도 동작하지만, 클라이언트 코드에서 사용하는 것은 권장하지 않습니다.
사용법
React 트리를 HTML 문자열로 렌더링하기
renderToString
을 호출하면 앱을 HTML 문자열로 렌더링할 수 있으며, 서버 응답으로 전송할 수 있습니다.
import { renderToString } from 'react-dom/server';
// 라우트 핸들러 문법은 백엔드 프레임워크에 따라 다릅니다.
app.use('/', (request, response) => {
const html = renderToString(<App />);
response.send(html);
});
이렇게 하면 React 컴포넌트의 초기 비인터랙티브 HTML이 생성됩니다. 클라이언트에서는 hydrateRoot를 호출해 해당 HTML을 인터랙티브하게 만들 수 있습니다.
⚠️
renderToString
은 스트리밍이나 데이터 로딩 대기를 지원하지 않습니다. 아래 대안 참고.
Alternatives
renderToString에서 서버 스트리밍 렌더로 마이그레이션
renderToString
은 문자열을 즉시 반환하므로, 콘텐츠가 로드되는 대로 스트리밍할 수 없습니다.
- Node.js 환경: renderToPipeableStream 사용 권장
- Deno/Edge/Web Streams 환경: renderToReadableStream 사용 권장
서버가 스트림을 지원하지 않는 경우에만 renderToString을 계속 사용하세요.
renderToString에서 서버 정적 프리렌더로 마이그레이션
renderToString
은 문자열을 즉시 반환하므로, 정적 HTML 생성 시 데이터 로딩 대기를 지원하지 않습니다.
- Node.js 환경: prerenderToNodeStream 사용 권장
- Deno/Edge/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를 import하면 번들 크기가 불필요하게 커집니다. 브라우저에서 컴포넌트를 HTML로 렌더링하려면 createRoot로 DOM에 렌더링 후 innerHTML을 읽으세요.
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이 업데이트됩니다.
Troubleshooting
컴포넌트가 suspend되면 항상 fallback이 HTML에 포함됨
renderToString
은 Suspense를 완전히 지원하지 않습니다. 컴포넌트가 suspend(lazy, 데이터 fetch 등)되면, 가장 가까운
이 문제를 해결하려면 스트리밍 솔루션을 사용하세요. 서버 사이드 렌더링에서는 콘텐츠가 준비되는 대로 청크 단위로 스트리밍되어, 클라이언트 코드가 로드되기 전에도 점진적으로 페이지가 채워집니다. 정적 사이트 생성에서는 모든 콘텐츠가 준비될 때까지 대기한 후 정적 HTML을 생성합니다.
출처: https://react.dev/reference/react-dom/server/renderToString