-
hydrationWeb Dev/3. React 관련 2021. 5. 19. 23:15728x90
https://github.com/hayoung0Lee/complete-intro-to-react/tree/ssr
ssr을 이번에 다시 한번 복습을 했는데, 왜 Next.js가 인기가 많은지 다시한번 알게 되는 시간이었다.
Server - renderToString
위의 예시는 express server를 통해서 server에서 이미 렌더링이 된 파일을 먼저 내려보내준다. 이때 App을 렌더링해야하는데, App 컴포넌트내에서 browserRouter(window 객체 참조)를 쓰고있는데, server에서는 window객체가 없으므로 StaticRouter로 감싸준다.
import express from "express"; import { renderToString } from "react-dom/server"; import { StaticRouter } from "react-router-dom"; import fs from "fs"; import App from "../src/App"; const PORT = process.env.PORT || 3000; const html = fs.readFileSync("dist/index.html").toString(); const parts = html.split("not rendered"); const app = express(); app.use("/dist", express.static("dist")); app.use((req, res) => { const staticContext = {}; const reactMarkup = ( <StaticRouter url={req.url} context={staticContext}> <App /> </StaticRouter> ); res.status(staticContext.statusCode || 200); res.send(`${parts[0]}${renderToString(reactMarkup)}${parts[1]}`); res.end(); }); console.log(`listening on http://localhost:${PORT}`); app.listen(PORT);
RenderToString 는 React에서 제공하는데, 컴포넌트를 넘겨주면, html string을 뽑아준다. 이때 이렇게 컴포넌트를 변환한다음, index.html의 root부분에 끼워준다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Adopt me</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div id="modal"></div> <!-- React가 render하는 곳 --> <div id="root">not rendered</div> <!-- 여기 renderToString한거 끼워줌 --> <script src="ClientApp.js"></script> </body> </html>
ClientApp.js - hydrate
이러고 나서는 response로 갈텐데 위의 파일을 보면 알겠지만 html파일 자체에서는 ClientApp.js를 부르고 있다.
import { hydrate } from "react-dom"; import { BrowserRouter, BrowserRouter as Router } from "react-router-dom"; import App from "./App"; hydrate( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById("root") );
ClientApp.js에서는 hydrate를 하고 있다. 이건 html 이 이미 renderToString같은 것으로 이미 렌더링 된 경우에 hydrate하기 위해서 사용된다. React가 이미 존재하는 마크업에 이벤트 리스너를 달아서 react컴포넌트화 하는 과정이다.
react는 server와 client의 컨텐츠가 동일할것을 기대한다. 어느정도 미스매칭은 커버를 해주는 것 같은데, warning이 뜰수도 있긴한가보다.
드디어 말귀를 이해한 좋은 글
https://simsimjae.tistory.com/389
hydration이 매번 이해가 안되서 이글을 여러번봤었는데 드디어 좀 이해가 된다.
여튼 SSR을 하는 경우에는 성능이 더 좋아진게 맞는지 측정을 제대로 하는 것이 필요하다고 한다. 왜냐하면 server에서 렌더링 하는 시간 + html 파일도 보내줘야하고 + 기존처럼 js파일도 다 보내기때문.
'Web Dev > 3. React 관련' 카테고리의 다른 글
React관련 싹 훑기(3) - Redux 의 개념 (0) 2021.05.21 React관련 싹 훑기(2) - Intermediate react 세미나 듣고.. (0) 2021.05.20 lazy, Suspense (0) 2021.05.19 useRef, useImperativeHandle (0) 2021.05.19 useEffect vs useLayoutEffect (0) 2021.05.19