React를 실행시키면 브라우저에 index.html을 보내는데, 이 html은 비어있고, js코드로 화면을 그린다.
React에서 컴포넌트에 html처럼 생긴 코드를 작성하지만 이는 jsx문법이고, 리액트에서 실제로는 createElement라는 메서드를 통해 그려진다.
그래서 react로 작성된 코드는 브라우저가 js파일을 받아 직접 렌더링과정을 거치기때문에 초기 렌더링시간이 오래 걸린다고하는것이다.(아마..?)
그래서 react는 csr방식이라고 하는것이다.
그런데 react를 ssr처럼 동작하게 할수있는 방법을 찾아보던 중 아래와 같은 방법도 있다는 것을 발견했다.(사실 next.js는 react + ssr 이기 때문에 ssr처럼 만들고싶으면 그냥 next를 써라)
ReactDOMServer
를 통해 컴포넌트를 정적 마크업으로 렌더링할 수 있습니다.
다음 메서드는 서버와 브라우저 환경에서 사용할 수 있습니다.
아래 메서드는 서버에서만 사용할 수 있는 stream
패키지에 의존성이 있어 브라우저에서는 작동하지 않습니다.
ReactDOMServer.renderToString(element)
이미 서버 렌더링 된 마크업이 있는 노드에서 ReactDOM.hydrate()를 호출하는 경우, React는 이를 보존하고 이벤트핸들러만 연결함
hydrate는 뭐야?
기존에 서버 사이드 렌더링된 결과물이 있을 경우 새로 렌더링하지 않고 기존에 존재하는 UI에 이벤트만 연동하여 애플리케이션을 초기 구동할 때 필요한 리소스를 최소화함으로써 성능을 최적화해줍니다.
ReactDOMServer.renderToString(element)
renderToString
과 비슷하지만 data-reactroot
와 같이 React에서 내부적으로 사용하는 추가적인 DOM 어트리뷰트를 만들지 않습니다.우선 react + ssr 의 순서를 보면
서버의 코드를 보면 노드로 되어있는데, 스프링으로 할수있는 방법을 찾아야할것같다.
암튼 아래의 코드를 보면 renderToString메서드에 보여주고자 하는 엘리먼트를 넣어준다.
import React from "react";
import { renderToString } from "react-dom/server";
import express from "express";
import App from "../src/App";
const app = express();
const PORT = 3005;
app.get("/", (req, res) => {
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<title>React App</title>
</head>
<body>
<div id="root">${renderToString(<App />)}</div>
<div>hello from server side</div>
</body>
</html>
`);
});
app.listen(PORT, () => console.log(`http://localhost:${PORT}`));
그리고 클라이언트에서는 hydrate를 해준다.
ReactDOM.hydrate(<App />, document.getElementById("root"));
👇🏻 아래 링크로 들어가보면 스프링으로 구현한 예시를 볼수있다.