[React.js] #3 React Router(with. react-router-dom)
위키 백과를 살펴보면 라우터의 사전적인 의미는 다음과 같아요.
# 라우터의 사전적 의미
라우터(router[a]혹은라우팅기능을 갖는 공유기)는 패킷의 위치를 추출하여, 그 위치에 대한 최적의 경로를 지정하며, 이 경로를 따라 데이터 패킷을 다음 장치로 전향시키는 장치이다.
간단하게 해석해보면 경로를 찾아주는 역할을 합니다.
리액트(SPA)에서의 라우터는 클라이언트 사이드에서 다양한 페이지에 접근이 가능하도록 합니다.
리액트에서 가장 많이 사용하는 패키지는 "react-router-dom"이며 해당 패키지의 사용법에 대해서 알아보겠습니다.
# 설치
yarn add react-router-dom
npm install react-router-dom
"react-router-dom"의 문서를 확인해보면 기능은 크게 "BrowserRouter", "Link", "Switch", "Route", 총 4가지로 나뉩니다.
# 기본적인 Router 사용방법을 알아보자
우선, 라우터 기능을 동작하기 위해서는 해당 컴포넌트가 "BrowserRouter" 하위에 존재해야 합니다.
<BrowserRouter>는 HTML5 API를 통해 URL과 동기화하여 UI를 유지합니다.
테스트를 진행하기 위해 <App> 컴포넌트에서 Router가 잘 작동할 수 있도록 <BrowserRouter>로 감싸줍니다.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
다음은 App 컴포넌트입니다.
import { Link, Route, Switch} from 'react-router-dom';
function App() {
return (
<div className="App">
<ul>
<li>
<Link to="/"> frist link </Link>
</li>
<li>
<Link to="/a"> A link </Link>
</li>
<li>
<Link to="/b"> B link </Link>
</li>
</ul>
<Route path="/" component={DefaultComp}></Route>
<Route path="/" component={AComp}></Route>
<Route path="/a" component={AComp}></Route>
<Route path="/b" component={BComp}></Route>
</div>
);
}
const DefaultComp = () => {
return (
<div> Default component </div>
)
}
const AComp = () => {
return (
<div> A Component </div>
)
}
const BComp = () => {
return (
<div> B Component </div>
)
}
export default App;
App 컴포넌트는 3개의 링크를 가지며, 해당 태그를 클릭할 경우 <Link to='/path'>에 설정된 경로로 이동합니다.
선택된 경로는 <Route>에 등록된 path를 찾아가며 일치하는 path에 등록된 컴포넌트를 랜더링 합니다.
위의 예제의 경우 첫번째<Route>와 두 번째 <Route>가 basePath("/")에 포함되므로 DefaultComp와 AComp를 화면에 랜더링 하게 됩니다.
그렇다면 "/b" 경로로 이동하는 경우는 어떤 결과가 발생될까요?
"/a"의 링크로 이동한 경우 총 3개의 컴포넌트가 랜더링 되고 있습니다.
위의 두 개(Default Comp와 A Comp)는 "/"에 포함되는 컴포넌트가 랜더링 되며
마지막으로는 "/b"에 포함되는 컴포넌트인 <BComp>가 랜더링 되게 됩니다.
이렇게 경로가 중복되는 경우 여러 개의 컴포넌트가 랜더링 되게 되는데, 이를 방지하기 위해 사용하는 것이 <Switch>입니다.
그럼 코드를 약간 수정해 보겠습니다.
<Switch>
<Route path="/" component={DefaultComp}></Route>
<Route path="/" component={AComp}></Route>
<Route path="/a" component={AComp}></Route>
<Route path="/b" component={BComp}></Route>
</Switch>
경로를 "/"로 이동했음에도 DefaultComp만 랜더링 되고 있습니다.
왜일까요..?
<Switch>의 경우 여러 개의 <Route>에서 path에 대한 충돌이 발생하지 않도록 관리해주는 역할을 하며 가장 처음에 매칭 되는 경로에 대한 <Route>만 실행하여 충돌을 방지해줍니다.
그렇다면 이번에는 A link로 이동했을 때 AComp를 랜더링 하고 B link 이동했을 때 BComp로 이동하고 싶은 경우 어떻게 수정해야 할까요?
<Switch>
<Route exact path="/" component={DefaultComp}></Route>
<Route path="/a" component={AComp}></Route>
<Route path="/b" component={BComp}></Route>
</Switch>
exact path로 설정하는 경우 path와 정확하게 일치하는 경우만 <Route>를 통해 이동할 수 있습니다.
# 라우터에서 특정 값들을 전달받기 위해서는 어떻게 해야 할까?
<Route>로 설정된 컴포넌트의 경우 history, location, match 총 세 가지의 porps를 전달받습니다.
각각의 객체에는 다음과 같은 정보를 담고 있습니다.
우선 <Link> 태그를 수정해 보도록 하겠습니다.
<div className="App">
<ul>
<li>
<Link to="/"> frist link </Link>
</li>
<li>
<Link to="/a/param?test=123"> A link </Link>
</li>
<li>
<Link to="/b/param?tt=224"> B link </Link>
</li>
</ul>
<Switch>
<Route exact path="/" component={DefaultComp}></Route>
<Route path="/a/:name" component={AComp}></Route>
<Route path="/b/:phone" component={BComp}></Route>
</Switch>
</div>
A Link와 B Link에 하위 url 경로와 queryString을 가지는 url로 변경하였고
<Route>에서는 Url params를 가질 수 있도록 path를 변경해 주었습니다.
컴포넌트의 Props로 전달되는 객체들을 이용하기 위해서는 다음과 같이 수정해 봅시다.
수정을 통해 다양한 props를 비구조 할당을 통해 객체를 받아오고 사용할 수 있습니다.
const DefaultComp = ({history, location, match}) => {
console.log(match)
console.log(locatiion)
console.log(history)
return (
<div> Default component </div>
)
}
이렇게 React에서 사용하는 "react-router-dom" 패키지의 사용법에 대해 알아보았는데, 패키지에는 본 글에서 설명하지 않은 기능도 많이 포함하고 있습니다. 보다 정확한 내용을 알고 싶으신 분은 정식 도큐먼트를 참조해주시기 바랍니다.
탕빠이!