리액트는 SPA(Single Page Application) 방식으로써,
여러개의 페이지를 사용하며, 새로운 페이지를 로드하는 기존의 MPA 방식과 달리 새로운 페이지를 로드하지 않고 하나의 페이지 안에서 필요한 데이터만 가져오는 형태를 가져온다
예를 들면 사용자가 페이지를 이동할때 페이지가 재로드 하지 않고 필요한 데이터만 불러 렌더링 하는 방식이다.
이러한 방식을 사용하려면 라이브러리를 사용하여 페이지를 렌더링 해줘야 한다.
하지만 리액트가 공식적으로 지원하는 라우터 기능이 없기 때문에 라이브러리를 설치해야 한다.
라우팅 라이브러리는 여러가지가 있지만 가장 대중적인 React Router를 사용해보자
npm install react-router-dom
npm을 사용하여 라이브러리를 설치 하거나
yarn add react-router-dom
yarm을 사용하여 라이브러리를 설치한다.
설치가 완료 되었다면 설치되어있는 라이브러리들의 버전을 확인 할 수 있는 package.json파일을 열어서 "react-touter-dom"
이 설치 되어있는지 확인한다.
페이지의 이동이 생길 js페이지에서
리액트 라우터는 설치하여 가져온 라이브러리를 적용 해야한다.
다음과 같은 문구를 추가하여 리액트 라우터를 불러온다.
BrowserRouter : HTML5의 History API를 사용하여 페이지를 새로고침하지 않고도 주소를 변경할 수 있도록 해준다.
즉, 페이지 변경으로 인한 재로드(깜빡거림) 가 없다.
여기서 사용할때는 BrowserRouter을 Router로 이름을 바꾼다.(이름변경은 생략 가능하다)
Switch : Route들을 이 컴포넌트에 감싸면 매칭되는 첫번째 라우트만 보여주고 나머지는 보여주지 않는다.
Route : Route를 사용해 경로를 설정해준다.
이 세가지를 "react-router-dom"라이브러리에서 가져온다.
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Login from "./pages/Login/Login";
import Main from "./pages/Main/Main";
import "./styles/Reset.css";
class Routes extends React.Component {
render() {
return (
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/main" component={Main} />
</Switch>
</Router>
);
}
}
export default Routes;
1 (React-Route) : <Router>
를 시작하는 코드
(이 코드는 React-Route에서 이름을 <Router>
변경했으니 주의)<Router>
코드 안에 페이지를 이동할 컴포넌트를 넣으면 된다.
2 (Switch) : Route들을 이 컴포넌트에 감싸면 매칭되는 첫번째 라우트만 보여주고 나머지는 보여주지 않는다.(하나만 보여준다) 스위치를 쓰지 않으면 컴포넌트가 중복되어 사용 될 수 있다.
3 (Route) : Route를 사용해 컴포넌트를 지정해준다.
4 (exact) : 주어진 경로와 정확히 맞아 떨어져야만 설정한 컴포넌트를 보여준다. 첫번째 라우트/의 경우에는 주소가 "/"와 똑같이 떨어져야지 로그인 주소가 나오게 한다.
5 (path) : 경로를 path값으로 설정한다.
즉 변경될 주소를 적는다.
6 : 2번과 4번을 안쓴다면 로그인 홈페이지의 경로인 /
이 /main
에도 /
가 있기 때문에 동시에 매칭이 되어서 보여진다.
우리가 만든 파일에 맞춰서 index.js를 수정한다.
import React from "react";
import ReactDOM from "react-dom";
import Routes from "./Routes";
ReactDOM.render(<Routes />, document.getElementById("root"));
Route가 이동하는 방법은 여러가지가 있지만 2가지만 적어보려고 한다.
<Link>
컴포넌트 사용하는 방법import React from "react";
import "./Login.scss";
import { Link } from "react-router-dom";
class Login extends React.Component {
render() {
return (
<div className="login">
<main>
.............
</div>
<div className="sign-up-box">
<div>
계정이 없으신가요? <Link to="/signup">회원가입</Link>
</div>
</div>
</main>
</div>
);
}
}
export default Login;
react-router-dom
에서 제공하는 <Link>
컴포넌트는 DOM에서 <a>
로 변환(Compile) 된다.
기존에 HTML의 다른 페이지를 이동할때 a태그를 주어서 <a href="localhost:3000/">
이런식으로 이동을 했다 마찬가지도 리액트도 a 링크를 통해서 이동 할 수 있다. 단 그럴 경우 리액트를 쓰는 취지에 조금 벗어난다고 할 수 있다. 웹페이지가 SPA가 아니게 되어버린다.
리액트는 a링크 대신 <Link>
가 대신 사용한다고 보면 된다.
<Link to="/main"></Link>
링크를 클릭했을때 라우터 컴포넌트에 path의 경로가 "/main"과 일치해 component={Main}으로 이동한다.
import React from "react";
import "./Login.scss";
import { Link, withRouter } from "react-router-dom";
class Login extends React.Component {
goToMain = () => {
this.props.history.push("/main");
};
render() {
return (
<div className="login">
<main>
<div className="login-box">
......
</form>
<button
onClick={this.goToMain}
type="button"
id="login-button"
value="0"
.........
</main>
</div>
);
}
}
export default withRouter(Login);
<Link />
와는 다르게 사용하지 않고 요소에 onClick 이벤트를 통해 페이지를 이동하는 방법도 있다. goToMain
라는 event handler에서 구현한 것처럼 props 객체의 history 에 접근해서 이동할 수 있다.
받은 history
의 push
메서드의 인자로 Routes.js
에서 설정한 path를 넘겨주면, 해당 라우트로 이동할 수 있다.
이 컴포넌트(Login 컴포넌트)에서 props에 route 정보(history
)를 받으려면 export하는 컴포넌트에 withRouter
로 감싸주어야 한다.
어떨때 어떤 방법으로 사용하는게 좋을까?
1.<Link>
: 클릭 시 바로 이동하는 로직 구현 시에 사용한다.
ex)간단한 <a>
링크, Nav Bar, Aside Menu, 아이템 리스트 페이지에서 아이템 클릭 시 > 상세 페이지로 이동
2. withRouterHOC
: 페이지 전환 시 추가로 처리해야 하는 로직이 있는 경우 withRouterHOC 방법으로 구현한다.
ex) 로그인 버튼 클릭 시, Backend API로 데이터(User Info) 전송, User Data 인증 / 인가
리액트 라우터 공식 홈페이지 : https://reactrouter.com/web/guides/quick-start