React-router-dom 적용하기

시작하기

리액트 싱글페이지 SPA(Single page application)에서 다른페이지로 이동하고 싶을때 사용하는 라이브러리입니다.
create-react-app에서 라우터를 사용해 보겠습니다.

설치

npm install react-router-dom @types/react-router-dom

라우터 설정

index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.getElementById('root'));

serviceWorker.unregister();

최상단 App컴포넌트를 BrowserRouter로 감싸주어야 내부 컴포넌트에서 react-router-dom기능을 사용할 수 있습니다.

라우터를 관리할 Main.tsx 파일을 만들어 줍니다.

Main.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React from 'react';
import { Switch, Route } from 'react-router-dom';

const Main:React.FC = () => {
return (
<Switch>
<Route path="/about" component={About}/>
<Route path="/users" component={Users}/>
<Route path="/" component={Home}/>
</Switch>
)
}

export default Main;

const Home:React.FC = () => {
return <h2>Home</h2>;
}

const About:React.FC = () => {
return <h2>About</h2>;
}

const Users:React.FC = () => {
return <h2>Users</h2>;
}

Switch 태그 내부의 Route중에 path가 현재 라우터 값과 일치하는 컴포넌트를 뿌려줍니다.
Route 의 속성으로

  • component:컴포넌트
  • exact: 중복 되지않고 하나만 존재해야할때
  • path: 라우터 주소

라우터의 배치 순서도 중요합니다.
예를들어서 위의 예제를 통해 배치 순서도를 설명하겠습니다.
현재 URL을 http://localhost:3000/users 라고 가정하겠습니다.

  • 참고: /users와 같이 앞에 아무것도 없이 /가 있는 경우 루트를 의미합니다.
Main.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 이 경우에는 path가 /인 Home컴포넌트가 실행됩니다.
<Switch>
<Route path="/" component={Home}/>
<Route path="/users" component={Users}/>
<Route path="/about" component={About}/>
</Switch>

// 정상적으로 path가 /users인 Users컴포넌트가 실행됩니다.
<Switch>
<Route path="/users" component={Users}/>
<Route path="/about" component={About}/>
<Route path="/" component={Home}/>
</Switch>

// 다른방법으로 exact를 사용하는 방법이 있습니다.
<Switch>
<Route exact path="/" component={Home}/>
// exact는 exact={true}을 줄인것입니다.
// 오로지 url이 / 루트일때만 Home을 실행합니다.
<Route path="/users" component={Users}/>
<Route path="/about" component={About}/>
</Switch>

라우터를 설정할때 위에서부터 아래로 차례차례 읽습니다.
순서에 맞게 라우터를 설정해 주면됩니다.

App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React from 'react';
import { Link } from 'react-router-dom';
import Main from './Main';

const App = () => {
return (
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
<Main />
</div>
);
}
export default App;

코드를 보시면 Link라는 컴포넌트를 사용했습니다. Link에 to속성으로 url을 넣어줍니다.
중요한 컴포넌트로, 이 컴포넌트의 기능은 다른 라우터로 이동하게 해주는 <a>태그와 비슷한 기능을 합니다.
하지만 중요한 차이점이 있습니다.
a태그를 사용할시에는 웹사이트 페이지가 새로고침이 됩니다. 그렇게 되면 페이지를 다시 읽어 내는 것이기에 속도가 조금 느릴수 밖에 없습니다.
하지만 Link는 페이지를 새로고침하지 않으면서 라우터를 빠르게 이동할수 있습니다.

a태그와 Link컴포넌트 비교
a태그의 경우 상단에 로딩바가 계속생겨나는 것이 보입니다.
하지만 Link의 경우 로딩바없이 바로바로 라우터 변경이 되는것을 확인할 수 있습니다.
현재이미지의 경우 많은 정보가 없기 때문에 차이점이 적게 느껴지지만 사이트가 커질수록 더 많은 차이를 느낄수 있습니다.

Router hooks

react-router-dom에서도 훅스를 지원합니다.
React가 16.8.X보다 높은 버젼이어야합니다.

App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React from 'react';
import { Link } from 'react-router-dom';
import Main from './Main';

const App = () => {
return (
<div>
// ...
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
<li>
<Link to="/movie/marvel">마블</Link>
</li>
<li>
<Link to="/movie/dc-comics">DC코믹스</Link>
</li>
// ...
</div>
);
}
export default App;

useParams

Main.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from 'react';
import { Switch, Route, useParams } from 'react-router-dom';

const Main:React.FC = () => {
return (
<Switch>
//..
<Route path="/movie/:type" component={Movie}/>
<Route path="/" component={Home}/>
</Switch>
)
}

export default Main;

const Movie:React.FC = () => {
const { type } = useParams();
return (<div>
<h2>Movie</h2>
<p>{type}</p>
// "marvel"
</div>)
}

useParams로 /movie/:type :뒤에 있는 파라미터 값을 가져올 수 있습니다.

useLocation

1
2
3
4
5
6
7
8
9
import { useLocation } from 'source/_posts/frontend/react-router-dom/react-router-dom';
const location = useLocation();
{
hash: ""
key: "hhedtc"
pathname: "/movie/marvel"
search: ""
state: undefined
}

useRouteMatch

1
2
3
4
5
6
7
8
import { useRouteMatch } from 'source/_posts/frontend/react/react-router-dom';
const { type } = useRouteMatch();
{
isExact: true
params: {type: "marvel"}
path: "/movie/:type"
url: "/movie/marvel"
}

useHistory

1
2
3
4
5
6
7
8
9
10
11
import { useHistory } from "source/_posts/frontend/react/react-router-dom";

const Button = () => {
const history = useHistory();
const handleClick = () => {
history.push("/home");
}
return (
<button onClick={() => handleClick()}>GO HOME</button>
);
}

useHistory에서 push/replace를 통해 페이지를 이동할수있습니다.

push/replace 차이점

1
2
history.push("/home"); // home으로 페이지 이동하고 뒤로가기가 가능합니다.
history.replace("/home"); // home으로 페이지 이동하고 뒤로가기가 불가능합니다.
Share