react-router-dom을 이용해 Client Side Routing을 구현해보았다.
페이지가 전환되지 않는 SPA(Single Page App) 임에도 주소창이 변환되는 것을 확인할 수 있었다.
말 그대로, 페이지가 1개인 어플리케이션이란 뜻이다.
전통적인 웹어플리케이션의 구조는, 여러페이지로 구성되어있다. 유저가 요청할 때마다 페이지가 새로고침되며, 페이지를 로딩할 때마다 서버로부터 리소스를 전달받아 해석 후 렌더링을 한다. HTML파일, 혹은 템플릿 엔진 등을 사용해서 어플리케이션의 뷰가 어떻게 보여질지도 서버에서 담당했다.
<문제점>
요즘은 웹에서 제공되는 정보가 정말 많기 때문에 속도적인 측면에서 문제가 있었고, 이를 해소하기 위하여 캐싱과 압축을 하여 서비스가 제공되는데, 이는 사용자와 인터렉션이 많은 모던 웹 어플리케이션에서는 충분하지 않을 수도 있습니다. 렌더링 하는 것을 서버쪽에서 담당한다는 것은, 그만큼 렌더링을 위한 서버 자원이 사용되는 것이고, 불필요한 트래픽도 낭비가 됩니다.
<해결방안>
리엑트 같은 라이브러리 혹은 프레임워크를 사용해서 뷰 렌더링을 유저의 브라우저가 담당하도록 하고, 우선 어플리케이션을 브라우저에 로드 한 다음에 정말 필요한 데이터만 전달받아 보여줍니다.
싱글페이지라고 해서, 한 종류의 화면만 있는 것은 아닙니다.
예를들어 블로그를 만든다면, 포스트 목록, 포스트, 글 쓰기 등의 화면이 있다고하면 화면에 따라 주소도 만들어 줘야합니다. 주소가 있어야, 유저들이 북마크도 할 수 있고 서비스에 구글을 통해 유입될 수 있기 때문입니다.
다른 주소에 따라 다른 뷰를 보여주는 것을 라우팅이라고 합니다.
리엑트 자체에는 이 기능이 내장되어 있지 않습니다.
따라서 우리가 직접 브라우저의 API를 사용하고 상태를 설정하여 다른 뷰를 보여 주어야 합니다.
react-router는 써드파티 라이브러리로서, 비록 공식은 아니지만(페이스북 공식 라우팅 라이브러리는 존재하지 않다.) 가장 많이 사용되고 있는 라이브러리 입니다. 이 라이브러리는 클라이언트 사이드에서 이뤄지는 라우팅을 간단하게 해준다. 게다가 서버 사이트 렌더링도 도와주는 도구들이 함께 딸려온다.
추가적으로 이 라우터는 react-native에서도 사용될 수 있다.
만약, 우리가 여러화면으로 구성된 웹 어플리케이션을 만들게 된다면, react-router는 필수 라이브러리이다.
*SPA의 단점
앱의 규모가 커지면 자바스크립트 파일 사이즈가 너무 커집니다.
유저가 실제로 방문하지 않을 수도 있는 페이지에 관련된 렌더링 관련 스크립트도 불러오기 때문입니다.
npm install react-router-dom
yarn add react-router-dom
SignUp.js
import React from "react";
import { Link } from "react-router-dom";
const SignUp = () => {
return (
<div className="body">
<div className="stage">
<div>
계정이 있으신가요? <Link to="/">로그인</Link>
</div>
</div>
</div>
);
};
export default SignUp;
SignUp.js
import React from "react";
import { Link } from "react-router-dom";
const SignIn = () => {
return (
<div className="body">
<div className="stage">
<div>
Don't have an account?
<Link to="/SignUp">Sign up</Link>
</div>
</div>
</div>
);
};
export default SignIn;
App.js
import React from "react";
import SignUp from "./components/SignUp";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import SignIn from "./components/SignIn";
function App() {
return (
<Router>
<Switch>
<Route exact={true} path="/">
<SignIn />
</Route>
<Route path="/SignUp">
<SignUp />
</Route>
</Switch>
</Router>
);
}
export default App;