hydration
https://github.com/hayoung0Lee/complete-intro-to-react/tree/ssr
hayoung0Lee/complete-intro-to-react
Contribute to hayoung0Lee/complete-intro-to-react development by creating an account on GitHub.
github.com
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이란?
hydration = 수화 수화란 우리 몸에 수분을 보충하는 행위를 뜻한다. 리액트에서 왜 hydration이라는 용어를 사용하는건지는 아래 내용을 살펴보고 다시 한번 생각해보자. 리액트는 DOM에 리액트 컴포
simsimjae.tistory.com
hydration이 매번 이해가 안되서 이글을 여러번봤었는데 드디어 좀 이해가 된다.
여튼 SSR을 하는 경우에는 성능이 더 좋아진게 맞는지 측정을 제대로 하는 것이 필요하다고 한다. 왜냐하면 server에서 렌더링 하는 시간 + html 파일도 보내줘야하고 + 기존처럼 js파일도 다 보내기때문.