본문 바로가기

Front-end/React

[React] React Router DOM (리액트 라우터 돔)

1. 라우팅이란?

웹 어플리케이션에서 라우팅이라는 개념은 사용자가 요청한 URL에 따라 알맞는 페이지를 보여주는 것을 의미한다.

리액트에서 라우트 시스템을 구축하기 위해 사용할 수 있는 선택지는 두가지가 있다.

  • 리액트 라우터(React Router) : 리액트의 라우팅 관련 라이브러리들 중에서 가장 오래됐고, 가장 많이 사용된다. 리액트 라우터는 컴포넌트 기반으로 라우팅 시스템을 설정할 수 있다.
  • Next.js: Next.js는 리액트 프로젝트의 프레임워크이다. 우리가 사용했던 Create React App처럼 리액트 프러젝트 설정을 하는 기능,라우팅 시스템,  최적화, 다국어 시스템 지원, 서버 사이드 렌더링 등 다양한 기능들을 제공한다. 이 프레임워크의 라우팅 시스템은 파일 경로 기반으로 작동한다. 이 프레임워크는 리액트 라우터의 대안으로 많이 사용되고 있다.

 

2. 리액트 라우터 적용 및 기본 사용법

  1. 진행중인 프로젝트로 이동해여 리액트 라우터 라이브러리 설치

$ cd router-tutorial
$ yarn add react-router-dom

2. 프로젝트에 적용

--> 프로젝트에 적용할 때는 react-route-dom에 있는 BrowserRouter를 임포트해서 사용한다.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

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

 

  3. Route 컴포넌트로 특정 경로에 원하는 컴포넌트 보여주기

--> 사용자의 브라우저 주소 경로에 따라 우리가 원하는 컴포넌트를 보여주기 위해서 Route라는 컴포넌트를 통해 라우트 설정을 해줘야 한다.

<Route path="주소규칙" element={보여 줄 컴포넌트 JSX} />
import { Route, Routes } from 'react-router-dom';
import About from './pages/About';
import Home from './pages/Home';

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
    </Routes>
  );
};

export default App;

--> About이라는 페이지와, Home이라는 컴포넌트를 미리 만들어놨다고 가정했을 때, <Routes> 컴포넌트 내부에 Route컴포넌트와 경로를 넣어준다. 이때 yarn start를 하면 첫 화면으로 Home 컴포넌트가 보여진다.

 

  4. Link 컴포넌트를 사용하여 다른 페이지로 이동하는 링크 보여주기

--> 웹 페이지에서는 원래 링크를 볼 때 a태그를 사용하지만, 리액트 라우터를 사용하는 프로젝트에서 a태그를 바로사용하면 안됨.

(a태그를 클릭하여 페이지를 이동할 때 브라우저에서는 페이지를 새로 불러오기 때문!!)

 

Link 컴포넌트 역시 a태그를 사용하긴 하지만, 페이지를 새로 불러오는 것을 막고 History API를 통해 브라우저 주소의 경로만 바꾸는 기능이 내장되어있다.

<Link to="경로">링크 이름</Link>

만약 Home페이지에서 About 페이지로 이동할 수 있도록 Link컴포넌트를 Home페이지 컴포넌트에서 사용한다면?

import { Link } from 'react-router-dom';

const Home = () => {
  return (
    <div>
      <h1>홈</h1>
      <p>가장 먼저 보여지는 페이지입니다.</p>
      <Link to="/about">소개</Link>
    </div>
  );
};

export default Home;

맨 처음 페이지
<소개>라는 링크를 눌렀을 때

이런 방식으로 페이지가 이동한다.

 

4. URL 파라미터와 퀴리 스트링

페이지 주소를 정의할 때 가끔은 유동적인 값을 사용해야 할 때도 있다. URL 파라미터와 쿼리스트링인데,

URL파라미터는 주소의 경로에 유동적인 값을 넣는 형태이고, 쿼리스트링은 주소의 뒷부분에 ?문자열 이후에 key=value 로 값을 정의하며 & 로 구분을 하는 형태이다. 

  • URL 파라미터 예시: /profile/velopert
  • 쿼리스트링 예시: /articles?**page=1&keyword=react

주로 URL 파라미터는 ID 또는 이름을 사용하여 특정 데이터를 조회할 때 사용하고, 쿼리스트링(Querystring)은 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용한다.

 

<URL 파라미터>

URL파라미터는 useParams 라는 Hook을 사용하여 객체형태로 조회할 수 있다. (URL파라미터의 이름은 라우트 설정을 할 때 Route 컴포넌트의 path props를 통하여 설정한다.)

import { useParams } from 'react-router-dom';

const data = {
  seo: {
    name: '이서영',
    description: '싸발 개발자',
  },
  you: {
    name: '최유진',
    description: '싸발싸발 개발자',
  },
};

const Profile = () => {
  const params = useParams();
  const profile = data[params.username];

  return (
    <div>
      <h1>사용자 프로필</h1>
      {profile ? (
        <div>
          <h2>{profile.name}</h2>
          <p>{profile.description}</p>
        </div>
      ) : (
        <p>존재하지 않는 프로필입니다.</p>
      )}
    </div>
  );
};

export default Profile;

// data객체에 예신 프로필 정보들을 key-value형태로 담아둠.
// Profile 컴포넌트에서는 username 파라미터를 통하여 프로필을 조회한 뒤에 프로필이 존재하지 않으면 
//'존재하지 않는 프로필입니다' 라는 문구를 보여주고, 존재한다면 프로필 정보를 보여줌

그리고 이후에  새로운 라우터를 추가해준다.

import { Route, Routes } from 'react-router-dom';
import About from './pages/About';
import Home from './pages/Home';
import Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="/profiles/:username" element={<Profile />} /> //**
    </Routes>
  );
};

export default App;

URL 파라미터는 /profiles/:username 과 같이 경로에 : 를 사용하여 설정한다.

그리고 Home 컴포넌트에 Link를 추가해준다.

import { Link } from 'react-router-dom';

const Home = () => {
  return (
    <div>
      <h1>홈</h1>
      <p>가장 먼저 보여지는 페이지입니다.</p>
      <ul>
        <li>
          <Link to="/about">소개</Link>
        </li>
        <li>
          <Link to="/profiles/seo">서영이의 프로필</Link>
        </li>

<쿼리스트링>

 쿼리스트링을 사용할 때는 URL 파라미터와 달리 Route 컴포넌트를 사용할 때 별도로 설정해야되는 것은 없다.

import { useLocation } from 'react-router-dom';

const About = () => {
  const location = useLocation();

  return (
    <div>
      <h1>소개</h1>
      <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
      <p>쿼리스트링: {location.search}</p>
    </div>
  );
};

export default About;

//아까 있던 About페이지에 쿼리스트링을 추가함

**위의 useLocation 이라는 Hook은 location 객체를 반환하며 이 객체는 현재 사용자가 보고있는 페이지의 정보를 지니고 있다.  이 객체에는 다음과 같은 것들이 있다.

  • pathname: 현재 주소의 경로 (쿼리스트링 제외)
  • search: 맨 앞의 ? 문자 포함한 쿼리스트링 값
  • hash: 주소의 # 문자열 뒤의 값 (주로 History API 가 지원되지 않는 구형 브라우저에서 클라이언트 라우팅을 사용할 때 쓰는 해시 라우터에서 사용합니다.)
  • state: 페이지로 이동할때 임의로 넣을 수 있는 상태 값
  • key: location 객체의 고유 값, 초기에는 default 이며 페이지가 변경될때마다 고유의 값이 생성됨

https://velog.io/@velopert/react-router-v6-tutorial

 

React Router v6 튜토리얼

리액트 라우터 v6를 새로 접하시는 분들을 위한 튜토리얼을 작성했습니다. 리액트 라우터 v6 의 기본적인 사용법, 그리고 이 라이브러리에서 제공하는 다양한 유용한 기능들에 대해서 알아봅시

velog.io

5. 중첩된 라우터

(게시글 1, 2 , 3 컴포넌트가 존재할 때) 여기서 <게시글1>게시글을 열었을 때, 게시글의 하단에 목록을 보여줘야한다면 

<div>
  <h2>게시글 {id}</h2>
  <ArticleList />
</div>

//기존방식 : ArticleList 컴포넌트를 따로 만들어서 각 페이지 컴포넌트에서 사용

중첩된 라우터를 사용한다면

import { Route, Routes } from 'react-router-dom';
import About from './pages/About';
import Article from './pages/Article';
import Articles from './pages/Articles';
import Home from './pages/Home';
import Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="/profiles/:username" element={<Profile />} />
      <Route path="/articles" element={<Articles />}> //**
        <Route path=":id" element={<Article />} /> //**
      </Route>
    </Routes>
  );
};

export default App;

//새로 추가한 articles라는 컴포넌트는 게시글의 목록을 담은 컴포넌트

Articles 하위에 라우터 컴포넌트를 하나 더 추가해주고

import { Link, Outlet } from 'react-router-dom';

const Articles = () => {
  return (
    <div>
      <Outlet />
      <ul>
        <li>
          <Link to="/articles/1">게시글 1</Link>
        </li>
        <li>
          <Link to="/articles/2">게시글 2</Link>
        </li>
        <li>
          <Link to="/articles/3">게시글 3</Link>
        </li>
      </ul>
    </div>
  );
};

export default Articles;

 Outlet 이라는 컴포넌트를 사용해야한다. Outlet은 리액트 라우터에서 제공하는 컴포넌트.

그러면 위 코드에서 Outlet컴포넌트가 사용된 자리에 중첩된 라우트가 보여지게 된다.

 

5. 공통 레이아웃 컴포넌트

중첩된 라우트와 Outlet 은 페이지끼리 공통적으로 보여줘야 하는 레이아웃이 있을때도 유용하게 사용할 수 있다.

예를 들어서, Home, About, Profile 페이지에서 상단에 헤더를 보여줘야 하는 상황을 가정한다.

첫 번째 방법은 아마 Header 컴포넌트를 따로 만들어두고 각 페이지 컴포넌트에서 재사용을 하는 방법이다. 물론 이 방법이 틀린것은 아니지만, 방금 배운 중첩된 라우트와 Outlet을 활용하여 구현을 할 수도 있다. (중첩된 라우트를 사용하는 방식을 사용하면 컴포넌트를 한번만 사용해도 된다는 장점)

import { Outlet } from 'react-router-dom';

const Layout = () => {
  return (
    <div>
      <header style={{ background: 'lightgray', padding: 16, fontSize: 24 }}>
        Header
      </header>
      <main>
        <Outlet />
      </main>
    </div>
  );
};

export default Layout;

우선, 공통 레이아웃을 위한 Layout 컴포넌트를만든 뒤, '공통이 아닌' 부분에 Outlet 컴포넌트를 사용.

import { Route, Routes } from 'react-router-dom';
import Layout from './Layout';
import About from './pages/About';
import Article from './pages/Article';
import Articles from './pages/Articles';
import Home from './pages/Home';
import Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      <Route element={<Layout />}> //**
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/profiles/:username" element={<Profile />} />
      </Route> //**
      <Route path="/articles" element={<Articles />}>
        <Route path=":id" element={<Article />} />
      </Route>
    </Routes>
  );
};

export default App;

Layout 컴포넌트가 공통적으로 들어가야 할 컴포넌트를 Layout으로 감싸주면 하위 컴포넌트 들에 공통적으로 Layout이 보여지게 된다.

'Front-end > React' 카테고리의 다른 글

[React] React App 배포하기  (0) 2022.06.02
[React] React란 무엇인가? (feat. SPA와 Virtual DOM)  (1) 2022.04.10