20.4.5 스크립트로 스토어 초기 상태 주입하기
지금까지 작성한 코드는 API를 통해 받아 온 데이터를 렌더링하지만, 렌더링하는 과정에서 만들어진 스토어의 상태를 브라우저에서 재사용하지 못하는 상황입니다. 서버에서 만들어 준 상태를 브라우저에서 재사용하려면, 현재 스토어 상태를 문자열로 변환한 뒤 스크립트로 주입해 주어야 합니다.
index.server.js
(...) function createPage(root, stateScript) { return `<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="shortcut icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no" /> <meta name="theme-color" content="#000000" /> <title>React App</title> <link href="${manifest['main.css']}" rel="stylesheet" /> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"> ${root} </div> ${stateScript} <script src="${manifest['runtime~main.js']}"></script> ${chunks} <script src="${manifest['main.js']}"></script> </body> </html> `; } const app = express(); // 서버 사이드 렌더링을 처리할 핸들러 함수입니다. const serverRender = async (req, res, next) => { (...) const root = ReactDOMServer.renderToString(jsx); // 렌더링을 합니다. // JSON을 문자열로 변환하고 악성 스크립트가 실행되는 것을 방지하기 위해 <를 치환 처리 // https://redux.js.org/recipes/server-rendering#security-considerations const stateString = JSON.stringify(store.getState()).replace(/</g, '\\u003c'); const stateScript = `<script>_ _PRELOADED_STATE_ _ = ${stateString}</script>`; // 리덕스 초기 상태를 스크립트로 주입합니다. res.send(createPage(root, stateScript)); // 결과물을 응답합니다. }; (...)