Daylogs/Javascript

리액트 서버 렌더링 이해하기

ohgyun 2015. 11. 1. 14:54
발생일: 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)를 보면 참고하면 된다.
반응형