티스토리 뷰
발생일: 2015.10.21
키워드: react server rendering, 리액트 서버 렌더링, ReactDOMServer, ReactDOM, ReactDOMServer.renderToString
문제:
리액트 서버 렌더링을 구현해보려고 한다.
해결책:
먼저 전반적인 플로우에 대한 개념을 이해하면, 나머지를 적용하기 더 쉬울 것이다.
<서버>
S-1. 서버에 요청이 오면 클라이언트에 내려줄 데이터를 준비한 후, (A)
S-2. React 컴포넌트를 사용해 HTML 문자열로 변환해둔다. (B)
S-3. 클라이언트에는 데이터 (A)와 HTML 페이지 (B)를 함께 응답한다.
<클라이언트>
C-1. 클라이언트에서는 응답받은 HTML을 출력하고, (B)
C-2. 기존과 동일하게 리액트 컴포넌트를 시작하는데,
C-3. 서버에서 내려준 데이터 (A)를 초기 상태로 설정한다.
* 클라이언트에서는 렌더링된 엘리먼트를 기초로 데이터를 가져오는 것이 아니라,
서버에서 할당해준 값으로 다시 렌더링하는 것에 주의한다.
* React 0.14 버전부터 모듈이 분리됐다.
서버 렌더링에 사용하는 모듈을 ReactDOMServer, 클라이언트에서는 ReactDOM 을 사용하면 된다.
---
아주 간단한 샘플 코드를 작성했다.
<server.jsx>
// 요청이 들어오면,
app.get('/', (req, res) => {
// S-1. 클라이언트에 내려줄 데이터를 준비한 후,
let initialCount = 3;
let html = '<html><body>';
html += '<div id="container">';
// S-2. 리액트 컴포넌트로 HTML 문자열을 준비한다.
html += ReactDOMServer.renderToString(<Counter initialCount={initialCount} />);
html += '</div>';
// S-3. 클라이언트에 내릴 땐 데이터 포함해 응답한다.
html += `<script>window.initialCount = ${initialCount};</script>`;
html += '<script src="/js/client.js"></script>';
html += '</body></html>';
res.send(html);
});
<client.jsx>
// 클라이언트에서는 기존과 동일하게 리액트 컴포넌트를 시작하는데,
ReactDOM.render(
// C-3. 서버에서 내려준 값을 초기값으로 할당한다.
<Counter initialCount={window.initialCount} />,
document.getElementById('container')
);
나머지 자세한 코드는,
샘플 리파지터리(https://github.com/ohgyun/react-server-render-example)를 보면 참고하면 된다.
반응형
댓글
공지사항