React를 이용하면 SPA(Single Page Application)을 만들 수 있다. SPA란 페이지가 1개인 애플리케이션을 말한다. 여태까지 내가 만들어왔던 html파일들은 index.html
, main.html
.. 등등 이렇게 각 페이지마다 html파일들이 있었는데, 이제는 그렇게 하지 않고! 한 개의 웹페이지(html)안에서 이런 여러개의 페이지들을 보여줄 수 있는 방법을 배워보자! ✨
CRA(create-react-app)
로 setting 된 환경에서는 html 파일이 단 한 개만 들어 있다. 그리고 이 index.html 파일에서 <div id="root"></div>
← 이 부분에 우리가 띄우고 싶은 컴포넌트를 연결해서 브라우저에 띄우는데, Routing을 이용하면 준비한 여러 화면을 전환하면서 보여줄 수가 있다! 👀
즉, 라우팅이란? 다른 경로(url 주소)에 따라 다른 View(화면)을 보여주는 것이다.
🤚🏻 하지만 React는 프레임워크가 아닌 라이브러리이기때문에 라우팅 기능또한 기본적으로 내장되어있지 않다.
→ 그래서 Third Party Library를 이용해줘야 하고, 그 중에서 리액트의 라우팅 기능을 위해 가장 많이 사용되고있는 라이브러리는 React-router 이다. 🔥
다시한번 말하지만, Create React App(CRA)
에서 만든 환경에는 routing을 위한 로직이 들어있지 않기 때문에, routing solution인 이 react-router
를 추가해서 라우팅을 구현하는 것이다! ✨
npm install react-router-dom --save
🤚🏻 뒤에 --save
를 붙여주는 이유는 package.json
파일속 dependencies
부분에 지금 다운받는 react-router에 대한 정보(버전)을 확실하게 추가해주기 위해서 작성해주는거다.
index.js
파일에서 ReactDOM.render(<Routes />, document.getElementById("root"));
를 이용해 랜더시킬 Routes 컴포넌트를 만들어야한다.
import React, { Component } from "react"; import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; import Login from "./pages/Login/Login"; import Main from "./pages/Main/Main"; class Routes extends Component { render() { return ( <Router> <Switch> <Route exact path="/" component={Login} /> <Route exact path="/main" component={Main} /> </Switch> </Router> ); } } export default Routes;
import { //패키지
BrowserRouter as Router,
Switch,
Route,
} from 'react-router-dom';
→ 우선 react-router-dom 이라는 패키지로부터 <Router>
, <Switch>
, <Route>
를 불러옵니다.
import Login from "./pages/Login/Login"; //컴포넌트
import Main from "./pages/Main/Main"; //컴포넌트
→ 페이지에 표시할 component 들도 불러와줍니다!
class Routes extends Component {
render() {
return (
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/main" component={Main} />
</Switch>
</Router>
);
}
}
<Router>
: url을 따라 동기화를 시켜주는 역할<Switch>
Switch문이 case에 따라 실행을 해주는 것처럼, 케이스에 따라 연동을 시켜주는 역할<Route>
각각의 path와 component를 지정. ② import 부분 (2)
에서 import한 컴포넌트를 적어준다.)방금 만들어준 Routes component를 이제 index.js
에 추가시켜준다!
import React from "react";
import ReactDOM from "react-dom";
import Routes from "./Routes";
ReactDOM.render(<Routes />, document.getElementById("root"));
여태까지, routing을 위한 패키지를 설치했고, Routes 컴포넌트를 만들어서 각각 이동시킬 페이지들을 준비시켰다.
🤔 그럼 페이지간 이동은 어떻게 해야하지? → Route 이동을 하는 방법은 두가지가 있다.
1. <Link> 컴포넌트 사용
2. withRouterHOC 를 이용해 구현
<Link>
컴포넌트 사용import React from 'react';
import { Link } from 'react-router-dom';
class Login extends React.Component {
render() {
return (
<div>
<Link to="/signup">회원가입</Link>
</div>
)
}
}
export default Login;
Routes.js
에서 설정한 path로 이동하는 첫 번째 방법은 <Link>
컴포넌트를 사용하는 방법이다.react-router-dom
에서 제공하는 <Link>
컴포넌트는 DOM에서 <a>
로 변환(Compile) 된다.<a>
태그와 마찬가지로 <Link>
태그도 지정한 경로로 바로 이동시켜주는 기능을 한다.<a>
vs. <Link>
<a>
- 외부 사이트로 이동하는 경우<Link>
- 프로젝트 내에서 페이지 전환하는 경우import React from 'react';
import { withRouter } from 'react-router-dom';
class Login extends React.Component {
goToMain = () => {
this.props.history.push('/signup');
}
// 실제 활용 예시
// goToMain = () => {
// if(response.message === "valid user"){
// this.props.history.push('/main');
// } else {
// alert("너 우리 회원 아님. 가입 먼저 해주세요")
// this.props.history.push('/signup');
// }
// }
render() {
return (
<div>
<button
className="loginBtn"
onClick={this.goToMain}
>
로그인
</button>
</div>
)
}
}
export default withRouter(Login);
<Link />
를 사용하지 않고 요소에 onClick 이벤트를 통해 페이지를 이동하는 방법도 있다.goToMain
라는 event handler에서 구현한 것처럼 props 객체의 history (this.props.history
) 에 접근해서 이동할 수 있다.history
의 push
메서드의 인자로 Routes.js
에서 설정한 path를 넘겨주면, 해당 라우트로 이동할 수 있다.history
)를 받으려면 export하는 컴포넌트에 withRouter
로 감싸주어야 한다.withRouter
와 같이 해당 컴포넌트를 감싸주는 것을 Higher Order Component (이하 HOC) 라고 한다.<Link>
VS withRouterHOC 🔥①. <Link>
- 클릭 시 바로 이동하는 로직 구현 시에 사용한다.
- ex. Nav Bar, Aside Menu, 아이템 리스트 페이지에서 아이템 클릭 시 > 상세 페이지로 이동
②. withRouterHOC
- 페이지 전환 시 추가로 처리해야 하는 로직이 있는 경우 withRouterHOC 방법으로 구현한다.
- ex. 로그인 버튼 클릭 시
- Backend API로 데이터(User Info) 전송
- User Data 인증 / 인가
- response message
- Case 1 : 회원 가입되어 있는 사용자 > Main 페이지로 이동
- Case 2 : 회원 가입이 되어 있지 않은 사용자 > Signup 페이지로 이동