CSR이 여기서 필요한 이유는 SPA기반 SSR은 CSR앱을 이용해 서버에서 렌더링하는 것이기 때문입니다. 또한 SPA기반 SSR은 클라이언트가 페이지에 최초 접속시, 정확히 말하자면 SSR을 담당하는 서버에 요청을 보내는 과정에서만 SSR이 이루어지고, 그 이후 렌더링 과정은 CSR로 이루어지기 때문입니다.
import React from "react" ;
const About = () => {
return (
<div>
<h3>This is About page</h3>
</div>
);
};
export default About;
import React from "react" ;
const Home = () => {
return (
<div>
<h3>This is Home page</h3>
</div>
);
};
export default Home;
import React, { useState, useEffect } from "react" ;
import Home from "./Home" ;
import About from "./About" ;
function App ({ page: initialPage }) {
const [page, setPage] = useState(initialPage);
useEffect(() => {
window.onpopstate = (event) => {
setPage(event.state);
};
}, []);
function onChangePage (e) {
const newPage = e.target.dataset.page;
window.history.pushState(newPage, "" , `/${newPage}`);
setPage(newPage);
}
const PageComponent = page === "home" ? Home : About;
return (
<div>
<button data-page="home" onClick={onChangePage}>
Home
</button>
<button data-page="about" onClick={onChangePage}>
About
</button>
<PageComponent />
</div>
);
}
export default App;
import React from "react" ;
import ReactDOM from "react-dom" ;
import App from "./App" ;
ReactDOM.render(<App page="home" />, document.getElementById("root" ));
<!DOCTYPE html>
<html lang="kr" >
<head>
<meta charset="UTF-8" >
<title>test-ssr</title>
</head>
<body>
<div id="root" ></div>
</body>
</html>
const path = require("path" );
const HtmlWebpackPlugin = require("html-webpack-plugin" );
module .exports = {
mode: "production" ,
entry: "./src/index.js" ,
output: {
filename: "[name].[chunkhash].js" ,
path: path.resolve(__dirname, "dist" ),
},
devServer: {
historyApiFallback: true ,
port: 9000 ,
},
module : {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: require.resolve("babel-loader" ),
},
],
},
plugins: [
new HtmlWebpackPlugin ({
template: "./template/index.html" ,
}),
],
};
const presets = ["@babel/preset-react" , "@babel/preset-env" ];
const plugins = [];
module .exports = { presets, plugins };
아래는 DevServer의 결과물입니다.