본문 바로가기

Study/React

[React.js] React Router 기본, 중첩 Router 사용하기

1. Routing이란?


웹을 사용할 때 전통적인 링크 연결방식은 HTML에서 a 태그를 사용하여 href 속성에 연결할 링크를 넣어주는 방식이다.

 

 

이러한 방식은 웹사이트의 규모가 크지 않을 때는 사용하는데 크게 불편함이 없지만 로드되는 컨텐츠나 페이지의 용량자체가 크다면 불편함을 초래할 수 있다. 애초에 링크로 연결되는 방식은 각각의 HTML 파일을 로드하는 것이기 때문에 새로운 페이지로 이동할 때마다 화면 깜빡임이 지속될 것이며 해당 페이지 자체 또는 로드할 컨텐츠의 용량이 크다면 사용자 입장에서는 불만이 생길 수 밖에 없을 것이다.

 

위에서 구현한 예시는 간단한 예제이기 때문에 그러한 불편함을 느끼기 어려울 것이나, 페이스북이나 인스타그램처럼 퓨어 텍스트보다 압도적으로 높은 용량의 이미지/영상 컨텐츠가 주를 이루는 페이지라면 체감될 것이다.

 

그래서 SPA(Single Page Application)이라는 수단이 도입되었으며, 이는 페이지를 로드하면서 페이지 내부의 모든 구성요소를 렌더링 하는 것이 아니라 페이지를 이동하면서 바뀌는 부분만 렌더링 하는 것이다.

 

라우팅을 사용한다면

 

 

이렇게 클릭하는 경우에 따라 바뀌는 아래 부분만 렌더링해서 보여주게 된다.

 

 

 

 

 

2. React Router 사용하기


우선 노드 모듈을 추가해 주어야 한다.

$ npm install react-router-dom

또는
$ yarn add react-router-dom

 

그리고 react-router-dom 모듈 안에 있는 <Link /> 모듈과 <BrowserRouter />, <Routes />, <Route /> 모듈을 사용해서 각각을 연결해준다.

 

여기에서 Link 태그는 기존의 a 태그 역할을 할 것이며, BrowserRouter, Routes, RouteLink 태그에 부여된 to 속성의 값을 따라 각각 다른 컴포넌트를 보여주게 된다.

 

예제 코드를 보면

 

import React from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";

export default function NavBar() {
  return (
    <SNavBar>
      <SListWrapper>
        <SListItems>
          <SListAnchor to="/">홈</SListAnchor>
        </SListItems>
        <SListItems>
          <SListAnchor to="/board">게시판</SListAnchor>
        </SListItems>
        <SListItems>
          <SListAnchor to="/mypage">마이페이지</SListAnchor>
        </SListItems>
      </SListWrapper>
    </SNavBar>
  );
}

const SNavBar = styled.ul`
  background-color: tomato;
  padding: 20px;
`;

const SListWrapper = styled.ul`
  display: flex;
  align-items: center;
`;

const SListItems = styled.li`
  list-style: none;
  padding-right: 15px;
`;

const SListAnchor = styled(Link)`
  text-decoration: none;
  color: #fff;
`;

 

<SListAnchor />Link 모듈을 사용해서 to 속성을 넣어준 것이다. to 속성에 부여된 URL을 따라 다른 컴포넌트를 보여주게 할 것이다.

 

import { BrowserRouter, Route, Routes } from "react-router-dom";
import Board from "./Board";
import Home from "./Home";
import MyPage from "./MyPage";
import NavBar from "./NavBar";
import "./styles.css";

export default function App() {
  return (
    <div className="wrap">
    
      <BrowserRouter>
        <NavBar />
        
        {/* Router 사용 */}
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/board" element={<Board />} />
          <Route path="/mypage" element={<MyPage />} />
        </Routes>
        
      </BrowserRouter>
      
    </div>
  );
}

 

여기에서 BrowserRouter는 HTML5의 history API를 사용하여 URL과 UI를 동기화 하는 것이다.

그 중심에 네비게이션바가 들어가고 네비게이션 바를 통해 전송되는 to 속성의 링크를 따라 라우트의 path와 동일 여부를 조회하여 라우터는 다른 화면을 보여주게 되는 것이다.

 

 

 

 

 

3. 중첩 라우터 사용하기


중첩 라우터를 사용하기 위해서는 부모 라우터에서 path*을 추가하여 뒤에 다른 요소가 붙어 라우터로 이동한 페이지 내부에서 다시 다른 컴포넌트를 렌더링 할 것임을 알려주어야 한다.

 

부모 라우터가 존재하는 App.js는

 

import { BrowserRouter, Route, Routes } from "react-router-dom";
import Board from "./Board";
import Home from "./Home";
import Main from "./Main";
import MyPage from "./MyPage";
import NavBar from "./NavBar";
import "./styles.css";

export default function App() {
  return (
    <div className="wrap">
      <BrowserRouter>
        <NavBar />
        <Routes>
          <Route path="/" element={<Main />} />
          <Route path="/home/*" element={<Home />} />
          <Route path="/board" element={<Board />} />
          <Route path="/mypage" element={<MyPage />} />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

 

홈 화면에서 중첩 라우터를 사용할 것이므로 홈 화면의 path 뒤에 아스터리스크를 붙여 뒤에 다른 무언가가 올 것임을 알려주었다.

 

이제 홈 컴포넌트로 가서 라우트를 사용하기 위해

 

import React from "react";
import styled from "styled-components";
import { Link, Route, Routes } from "react-router-dom";
import Introduce from "./Introduce";
import SayHello from "./SayHello";
import Others from "./Others";

export default function Home() {
  return (
    <SContentsWrapper>
      <SContentsInner>홈 입니다.</SContentsInner>
      <SHomeContentsWrapper>
        <SHomeContentsLink to="/home/introduce">자기소개</SHomeContentsLink>
        <SHomeContentsLink to="/home/say_hello">인사하기</SHomeContentsLink>
        <SHomeContentsLink to="/home/others">
          아무거나 적는 페이지
        </SHomeContentsLink>
      </SHomeContentsWrapper>
      
      {/* 중첩 Router 사용 */}
      <Routes>
        <Route path="introduce" element={<Introduce />} />
        <Route path="say_hello" element={<SayHello />} />
        <Route path="others" element={<Others />} />
      </Routes>
      
    </SContentsWrapper>
  );
}

const SContentsWrapper = styled.div`
  padding: 10%;
`;

const SContentsInner = styled.div`
  font-size: 30px;
  font-weight: bold;
`;

const SHomeContentsWrapper = styled.div`
  margin: 30px 0 0 0;
`;

const SHomeContentsLink = styled(Link)`
  display: block;
  text-decoration: none;
  color: #000;
  padding: 10px;
`;

 

기존 부모 라우터의 경로는 생략하고, 페이지 내에서 deep하게 이동할 자식 라우터의 경로만 작성해주면 된다.