Single Page Application(SPA)
서버로부터 새로운 페이지를 불러오지 않고 현재의 페이지에 컴포넌트를 통해 동적으로 다시 작성하여 클라이언트와 소통하는 웹 애플리케이션이다. 필요한 모든 소스는 하나의 페이지에서 새로고침 없이 동작하게 된다.
그러나, SPA를 기반으로 개발할 때 흔히 겪는 어려움 중 하나는 웹페이지의 라우팅이다. 기본적으로 SPA에서 라우팅을 구현하게 되면 url path가 아닌 현재 어떤 컴포넌트가 렌더링 되어야 하는지 state를 통하여 관리를 한다. 이렇게 되면 다음과 같은 문제가 발생하게 된다.
1. 컴포넌트가 전환되어도 브라우저 주소창의 URL은 고정되어 있기 때문에 특정 페이지에 대한 즐겨찾기 등록이 불가능하다.
2. 뒤로가기 버튼을 누르면 해당 앱 내에서 이전 페이지로 이동하는 것이 아니라 그 전에 서핑하던 다른 웹사이트로 이동해버린다.
3. 새로고침 버튼을 누르면 사용 중이던 컴포넌트가 아닌 무조건 최초에 렌더링 되었던 컴포넌트로 이동한다.
이를 극복하기 위한 라이브러리가 React Router이다.
React Router
React Router를 사용하면 앱에서 발생하는 라우팅이 location이나 history와 같은 브라우저 내장 API와 완벽하게 연동이 된다. 따라서 기존 웹 사이트에서 가능하던 url path를 통한 라우팅이 가능해짐과 동시에 페이지의 동작은 SPA를 따르게 된다.
해당 라이브러리에는 핵심 컴포넌트가 3가지 존재한다.
<Link>
HTML의 <a> 태그와 유사한 기능을 한다.
· to : <a> 태그의 href 와 같은 기능, 이동할 경로를 지정
<Route>
현재 주소창의 경로와 매치될 경우 보여줄 컴포넌트를 지정한다.
· path : 매치시킬 경로를 지정
· component : 매치되었을 때 보여줄 컴포넌트 할당
<Router>
<Route>와 <Link> 컴포넌트가 함께 유기적으로 동작하도록 묶어주는데 사용한다. <Route>와 <Link> 컴포넌트는 DOM 트리 상에서 항상 <Router>를 공통 상위 컴포넌트로 가져야 한다.
이제 라이브러리를 이용하여 간단하게 라우팅을 진행해보자. 먼저 라이브러리를 사용하기 위해 'react-router-dom' 패키지를 설치하고 'create-react-app'으로 리액트 애플리케이션을 생성해보자.
|
$ npm install react-router-dom --save |
|
|
|
$ create-react-app . |
설치한 패키지를 임포트하여 코드를 작성하자.
App.js
|
import React, {Component} from 'react'; |
|
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; |
|
|
|
import First from './First'; |
|
import Second from './Second'; |
|
import Third from './Third'; |
|
|
|
class App extends Component { |
|
render(){ |
|
return ( |
|
<div className="App"> |
|
<Router> |
|
<div> |
|
<ul> |
|
<li><Link to='/First'>First </Link></li> |
|
<li><Link to='/Second'>Second </Link></li> |
|
<li><Link to='/Third'>Third </Link></li> |
|
</ul> |
|
</div> |
|
<div> |
|
<Switch> |
|
<Route path='/First' component={First} /> |
|
<Route path='/Second' component={Second} /> |
|
<Route path='/Third' component={Third} /> |
|
</Switch> |
|
</div> |
|
</Router> |
|
</div> |
|
); |
|
} |
|
} |
|
|
|
export default App; |
First.js
|
import React,{ Component } from 'react'; |
|
|
|
class First extends Component { |
|
render(){ |
|
return ( |
|
<div> |
|
<h2>First</h2> |
|
</div> |
|
); |
|
} |
|
} |
|
|
|
export default First; |
Second.js
|
import React,{ Component } from 'react'; |
|
|
|
class Second extends Component { |
|
render(){ |
|
return ( |
|
<div> |
|
<h2>Second</h2> |
|
</div> |
|
); |
|
} |
|
} |
|
|
|
export default Second; |
Third.js
|
import React,{ Component } from 'react'; |
|
|
|
class Third extends Component { |
|
render(){ |
|
return ( |
|
<div> |
|
<h2>Third</h2> |
|
</div> |
|
); |
|
} |
|
} |
|
|
|
export default Third; |
각각의 메뉴 First, Second, Third에 대해 경로에 알맞은 컴포넌트가 매칭되어 나타나도록 라우팅을 해주었다. 항상 <Router> 컴포넌트 아래에 <Link>와 <Route> 컴포넌트가 함께 존재해야 한다. 만약 따로 위치하면 에러가 발생하여 페이지가 나타나지 않는다.
<Switch> 컴포넌트는 불필요한 트래픽을 방지한다. 요청된 url에 알맞은 컴포넌트만을 로드한다.
<Route> 컴포넌트의 'exact' props는 path 값이 완전히 일치할 경우에만 해당 컴포넌트를 불러오도록 지정해준다. 예를 들어 '/' 경로의 라우트에 exact를 설정하지 않았다면 리액트 서버가 '/community'의 경로 요청을 받았을 때 '/' 이 포함되어있기 때문에 Community 컴포넌트가 아닌 Home 컴포넌트를 반환하게 된다. 따라서 하위 경로를 무시하지 않도록 하기 위해 exact를 설정해주어야 한다.
이제 서버를 실행하여 제대로 라우팅이 되었는지 확인해보자.
'프로그램 > react' 카테고리의 다른 글
[react] props (0) | 2022.03.02 |
---|---|
[react] 리액트 초기 프로젝트 생성 (0) | 2022.03.02 |
Node Sass version 6.0.1 is incompatible with ^4.0.0 || ^5.0.0 (0) | 2021.07.01 |
리액트 프로젝트 생성 (0) | 2021.06.30 |
리액트 네이티브 프로젝트 만들기 (0) | 2021.06.28 |
댓글