[React.js] React Router DOM

React Router

image

리액트의 SPA(single page application) 구현에 가장 많이 쓰이는 라우터 중 하나

SPA : 화면의 header, footer, sidebar 등 다시 로드해도 변함이 없는 부분들은 그대로 유지한 채 변경되는 부분의 데이터만 가져와서 수정하는 웹사이트.

리액트로 SPA를 구현한다는 것은 곧 해당 요청에 맞는 컴포넌트만 라우팅하여 부분적으로 렌더링한다는 것을 의미한다.


이 때 요청에 맞는 컴포넌트를 매칭시키기 위해 react-router-dom을 사용



react-router, react-router-dom, react-router-native

react-router-dom : 웹에서 쓰이는 컴포넌트를 포함한다.

react-router-native : react-native를 활용한 앱개발에 쓰이는 컴포넌트를 포함한다.

react-router는 이 둘을 합친 패키지이다.

웹개발을 위해서는 react-router-dom만 설치하면 된다.



React Router DOM 사용법

설치

$ npm install react-router-dom


import

import { BrowserRouter, Route, Switch, Link } from "react-router-dom";


Router의 종류, 기능

<BrowserRouter>

react-router-dom의 라우터는 <BrowserRouter><HashRouter> 두가지가 있다. <BrowserRouter> 는 HTML5의 history API를 활용하여 UI를 업데이트하고 <HashRouter> 는 URL의 hash를 활용한 라우터입니다. 정적인(static)페이지에 적합하다.


보통 request와 response로 이루어지는 동적인 페이지를 제작하므로 <BrowserRouter> 가 보편적으로 쓰이므로 이 글에서도 <BrowserRouter> 를 사용하겠다.



<Route>

요청받은 pathname에 해당하는 컴포넌트를 렌더링한다.



<Switch>

path의 충돌이 일어나지 않게 <Route> 들을 관리한다.

<Switch> 내부에 <Route> 들을 넣으면 요청에 의해 매칭되는 <Route> 들이 다수 있을 때에 제일 처음 매칭되는 <Route> 만 선별하여 실행하기 때문에 충돌 오류를 방지해주며, <Route> 간에 이동 시 발생할 수 있는 충돌도 막아준다.

path와 매칭되는 <Route> 가 없을 때에 맨 밑에 default <Route> 의 실행이 보장된다. (path 속성을 명시하지 않은 <Route> )



<Link>

링크를 생성합니다.




사용예제

  1. <BrowserRouter> 를 불러온 후 <Link> 를 추가한다.
// ... 생략
function App() {
  return (
    <div className="App">
      <h1>App</h1>
      <BrowserRouter>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/beauty">Beauty</Link>
          </li>
          <li>
            <Link to="/game">Game</Link>
          </li>
        </ul>
      </BrowserRouter>
    </div>
  );
}
// 생략 ...

위 예제에서 a, href를 사용하지 않은 이유는 a, hrefHTML 태그로서 페이지 전체를 새로고침하기 때문이다.



  1. <Switch> 와 그 안에 <Route> 3개를 추가한다.
// ... 생략
function App() {
  return (
    <div className="App">
      <h1>App</h1>
      <BrowserRouter>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/beauty">Beauty</Link>
          </li>
          <li>
            <Link to="/game">Game</Link>
          </li>
        </ul>
        <Switch>
          <Route path="/"></Route>
          <Route path="/beauty"></Route>
          <Route path="/game"></Route>
        </Switch>
      </BrowserRouter>
    </div>
  );
}

// 생략 ...

<Link> 를 통해 생성된 요청을 <Route> 가 받게 됐다.

<Link> 의 to 속성과 동일한 path를 가지고 있는 <Route> 가 매칭된다.



  1. 렌더링할 컴포넌트를 생성하고 <Route> 의 component속성에 전달한다.
import React from "react";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";

function App() {
  return (
    <div className="App">
      <h1>App</h1>
      <BrowserRouter>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/beauty">Beauty</Link>
          </li>
          <li>
            <Link to="/game">Game</Link>
          </li>
        </ul>
        <Switch>
          <Route path="/" component={Home}></Route>
          <Route path="/beauty" component={Beauty}></Route>
          <Route path="/game" component={Game}></Route>
        </Switch>
      </BrowserRouter>
    </div>
  );
}

function Home() {
  return <div>Home component</div>;
}

function Beauty() {
  return <div>Beauty component</div>;
}

function Game() {
  return <div>Game component</div>;
}

export default App;

Home, Beauty, Game 컴포넌트를 생성하고 component 속성으로 전달했다.

이제 매칭된 <Route> 의 컴포넌트가 렌더링된다.

그러나 아래와 같이 오류가 발생한다.

image

클릭할 때마다 각각 / , /beauty, /game에 해당되는 요청을 잘 받고있지만

매칭되는 <Route> 의 component를 렌더링하지 않고 항상 Home 컴포넌트만 렌더링하고 있다.

그 이유는 <Route> 의 순서 때문이다.

<Route path="/" component={Home}></Route>
<Route path="/beauty" component={Beauty}></Route>
<Route path="/game" component={Game}></Route>

<Switch> 는 매칭되는 제일 첫번째의 <Route> 를 선별하는데, 첫번째 <Route> 의 path에 전달한 “/”는 모든 요청에 매칭된다. 따라서 항상 Home 컴포넌트만 렌더링 된 것이다.

이 때는 <Route> 에 exact 속성을 추가하면 된다.

exact 속성을 추가하면 pathname과 정확히 일치하는 때에만 해당 <Route> 를 매칭시킨다.

첫번째 <Route> 에 exact 속성을 추가한다.

<Route path="/" exact component={Home}></Route>
<Route path="/beauty" component={Beauty}></Route>
<Route path="/game" component={Game}></Route>

image

요청에 맞게 해당되는 컴포넌트가 렌더링 되었다.

댓글남기기