앞서 배운 React webgame은 순수 React를 가지고 프로그래밍 방법을 배워보는데 집중했다. 오늘은 이러한 컴포넌트들이 웹에서 어떻게 동작하는지에 대해 간단히 배워본다.
먼저 프로젝트에 react-router, react-router-dom 패키지 설치하자. react-router는 웹 뿐만 아니라 앱 환경에서도 사용할 수 있다. 앱 환경에서는 react-router-dom → react-router-app을 설치해주면 된다.
$ npm i react-router react-router-dom
실제로 react-router-dom
만 사용하며 그 뼈대인 react-router
는 react-router-dom
에서 사용한다.
react-router-dom이 설치되었다면, 실제 Router를 설정해보자.
import React from "react";
import { BrowserRouter } from "react-router-dom";
import Lotto from "./src/lotto/Lotto";
import RSP from "./src/rock-paper-scissors/RSP";
import NumberBaseball from "./src/number-baseball/NumberBaseball";
const Games = () => {
return (
<BrowserRouter>
<div>
<Route path="/number-baseball" component={NumberBaseball} />
<Route path="/rock-scissors-paper" component={RSP} />
<Route path="/lotto-generator" component={Lotto} />
</div>
</BrowserRouter>
);
};
export default Games;
위와 같이 각 컴포넌트를 BrowserRouter tag로 감싸주어야 한다. 혹은 위와 같은 방법이 싫다면 ReactDom.render
메서드에 넣어줘도 된다.
// client.jsx
ReactDom.render(<BrowserRouter><App /></BrowserRouter>, document.querySelector('#root'));
React는 실제 여러 페이지인 것처럼 보이는 하나의 페이지이다. 따라서 react-router-dom
에서 페이지 간의 이동은 a 태그를 사용하는 것이 아닌 react-router-dom
에서 제공하는 Link 메서드를 사용한다.
import React from "react";
import { BrowserRouter, HashRouter, Route, Link } from "react-router-dom";
import Lotto from "./src/lotto/Lotto";
import RSP from "./src/rock-paper-scissors/RSP";
import NumberBaseball from "./src/number-baseball/NumberBaseball";
const Games = () => {
return (
<BrowserRouter>
<Link to="/number-baseball">숫자야구</Link>
<Link to="/rock-scissors-paper">가위바위보</Link>
<Link to="/lotto-generator">로또추첨기</Link>
<div>
<Route path="/number-baseball" component={NumberBaseball} />
<Route path="/rock-scissors-paper" component={RSP} />
<Route path="/lotto-generator" component={Lotto} />
</div>
</BrowserRouter>
);
};
export default Games;
만약 위 설정을 dev로 실행한 뒤 실제 페이지 주소에 path를 넣어치면 좌측과 같은 에러 메시지가 나온다. 왜그럴까? 그 이유는 서버에서는 저 페이지에 대한 정보를 알 수 없기 때문이다.
각 페이지 라우팅에 대한 정보는 오직 client.jsx만이 각 페이지에 대한 정보를 알고 있으므로 위처럼 바로 주소로 유입시 에러가 발생한다. 이러한 설정을 서버에서 맞춰줘야하는데, 그렇게 하기 전 dev환경에서 해당 에러를 보고싶지 않다면 webpack.config 설정 내 devServer에서 historyApiFallback 옵션을 활성화 해주면 개선된다.
BrowserRouter와 비슷한 기능으로 HashRouter가 있다. 이번에는 HashRouter로 라우팅 구현을 해보자
const Games = () => {
return (
<HashRouter>
{/* Link, Router... */}
</HashRouter>
);
};
export default Games;
위처럼 설정 후 dev를 실행시키면 path에 #이 붙어있다. http://localhost:8080/#/number-baseball
해시라우터를 붙이면 위에서 설명한 서버에서 페이지를 알 수 없다는 오류를 방지할 수 있다.
서버가 해시(#) 뒷 부분에 대해 인식하지 못하기 때문이다. (서버는 모르지만 Client는 안다.)
이러한 특징은 검색엔진, SEO들의 정보수집 동작 시에 문제가 된다.
보통 검색엔진이나 SEO는 데이터를 브라우저에 물어보지 않고, 서버에 물어보기 때문이다.
만약 해시(#)가 있는 상태로 검색엔진 등이 정보를 Request하면 서버는 데이터를 모르기 때문에 정보를 주지못하고 이는 데이터 노출에 영향을 주게 된다.
위와 같은 이유로 실무에서 HashRouter를 잘 쓰지 않는 편이며. (물론 브라우저라우터를 사용해도 SEO를 위해 따로 셋팅이 필요하긴 하다) 보통 주소값이 중요하지않고, 데이터 수집의 필요성이 없는 페이지의 경우 HashRouter를 많이 쓴다.