번역 자료 / / 2025. 5. 28. 06:46

[react-dom/server 번역] renderToString

출처: 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와 동일해야 합니다.

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 등)되면, 가장 가까운 의 fallback만 HTML로 렌더링됩니다. 실제 콘텐츠는 클라이언트 코드가 로드될 때까지 나타나지 않습니다.

이 문제를 해결하려면 스트리밍 솔루션을 사용하세요. 서버 사이드 렌더링에서는 콘텐츠가 준비되는 대로 청크 단위로 스트리밍되어, 클라이언트 코드가 로드되기 전에도 점진적으로 페이지가 채워집니다. 정적 사이트 생성에서는 모든 콘텐츠가 준비될 때까지 대기한 후 정적 HTML을 생성합니다.


출처: https://react.dev/reference/react-dom/server/renderToString

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유