상세 컨텐츠

본문 제목

[리액트스타터2] 13장. 리액트 라우터로 SPA 개발하기

22-23/22-23 리액트 스타터 2

by mk020 2023. 1. 5. 10:28

본문

728x90

 

I. 라우팅이란?

  • 라우팅: 개념은 사용자가 요청한 URL에 따라 알맞은 페이지를 보여주는 것

블로그를 만든다고 가정한다면, 블로그 애플리케이션은 다음과 같은 페이지로 구성되어 있습니다.

  • 글쓰기 페이지: 새로운 포스트를 작성하는 페이지
  • 포스트 목록 페이지: 블로그에 작성된 여러 포스트의 목록을 보여주는 페이지
  • 포스트 읽기 페이지: 하나의 포스트를 보여주는 페이지

이렇게 여러 페이지로 구성된 웹 애플리케이션을 만들 때 페이지별로 컴포넌트들을 분리해가면서 프로젝트를 관리하기 위해 필요한 것이 바로 라우팅 시스템입니다.

 

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

  • 리액트 라우터(React Router) : 리액트의 라우팅 관련 라이브러리 중 가장 오래되고 가장 많이 사용, 컴포넌트 기반으로 라우팅 시스템을 설정
  • Next.js : 리액트 프로젝트의 프레임워크, 리액트 프로젝트 설정을 하는 기능, 라우팅 시스템, 최적화, 다국어 시스템 지원, 서버 사이드 렌더링 등 다양한 기능을 제공

이 프로젝트는 리액트 라우터를 사용하여 라우팅 시스템을 구축하겠습니다. 리액트 라우터를 사용하면 손쉽게 리액트 라우터로 싱글 페이지 애플리케이션(SPA)을 만들 수 있습니다. 

 

II. 싱글 페이지 애플리케이션(SPA)이란?

싱글 페이지 애플리케이션(Single Page Application)이란 하나의 페이지로 이루어진 애플리케이션입니다. 리액트 라우터를 사용하여 여러 페이지로 구성된 프로젝트를 만들 수 있다고 했는데 왜 싱글 페이지 애플리케이션이라고 불리는지 의문이 들 수 있습니다. 이를 이해하기 위해서는 싱글 페이지 애플리케이션이란 개념이 생기기 전에 사용되던 멀티 페이지 애플리케이션이 어떻게 작동하는지 살펴봐야 합니다.

 

멀티 페이지 애플리케이션
  • 멀티 페이지 애플리케이션에서는 사용자가 다른 페이지로 이동할 때마다 새로운 html을 받아옴
  • 페이지를 로딩할 때마다 서버에서 CSS, JS, 이미지 파일 등의 리소스를 전달받아 브라우저 화면에 보여줌
  • 사용자 인터렉션이 많고 다양한 정보를 제공하는 모던 웹 애플리케이션은 이 방식이 적합하지 않음
  • 새로운 페이지를 보여줘야 할 때마다 서버 측에서 모든 준비를 한다면 그만큼 서버의 자원을 사용하는 것이고, 트래픽도 더 많이 나올 수 있기 때문

 

그래서 리액트 같은 라이브러리를 사용해서 뷰 렌더링을 사용자의 브라우저가 담당하도록 하고, 우선 웹 애플리케이션을 브라우저에 불러와서 실행시킨 후에 사용자와의 인터렉션이 발생하면 필요한 부분만 자바스크립트를 사용하여 업데이트하는 방식을 사용합니다. 만약 새로운 데이터가 필요하다면 서버 API를 호출하여 필요한 데이터만 새로 불러와 애플리케이션에서 사용할 수 있게 된 것입니다.

싱글 페이지 애플리케이션
  • html은 한 번만 받아와서 웹 애플리케이션을 실행시킨 후, 이후에는 필요한 데이터만 받아와서 화면에 업데이트
  • 기술적으로는 한 페이지만 존재하지만, 사용자가 경험하기에는 여러 페이지가 존재하는 것처럼 느낄 수 있음
  • 리액트 라우터 같은 라우팅 시스템은 사용자의 브라우저 주소창의 경로에 따라 알맞은 페이지를 보여줌
  • 링크를 눌러서 다른 페이지로 이동할 때 서버에 다른 페이지의 html을 새로 요청하는 것이 아니라,
  • 브라우저의 History API를 사용하여 브라우저의 주소창의 값만 변경하고 기존의 페이지에 띄웠던 웹 애플리케이션을 그대로 유지하면서 라우팅 설정에 따라 또 다른 페이지를 보여주게 됩니다.

 

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

 이번 실습은 다음 흐름대로 진행됩니다.

  1. 프로젝트 생성 및 라이브러리 설치
  2. 페이지를 만들고 이동해보기
  3. URL 파라미터와 쿼리스트링 사용해보기
  4. 중첩된 라우트 구현하기
  5. 리액트 라우터의 부가기능 사용해보기

 

1. 프로젝트 생성 및 라이브러리 설치

리액트 라우터를 적용해 볼 리액트 프로젝트를 생성한 뒤, 해당 디렉터리로 이동하여 리액트 라이브러리를 설치합니다.

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

 

2. 프로젝트에 라우터 적용

프로젝트에 리액트 라우터를 적용할 때는 src/index.js 파일에서 react-router-dom에 내장되어 있는 BrowserRouter라는 컴포넌트를 사용하여서 감싸면 됩니다. 이 컴포넌트는 웹 애플리케이션에 HTML5의 History API를 사용하여 페이지를 새로 불러오지 않고도 주소를 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있도록 해 줍니다.

// App.js

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

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

 

3. 페이지 컴포넌트 만들기

사용자가 웹 사이트에 들어왔을 때 가장 먼저 보일 Home 페이지 컴포넌트와 웹 사이트를 소개하는 About 페이지 컴포넌트를 만들겠습니다. 

// src/pages/Home.js

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

export default Home;
// src/pages/About.js

const About = () => {
  return (
    <div>
      <h1>소개</h1>
      <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
    </div>
  );
};

export default About;

이제 페이지로 사용할 컴포넌트들이 준비되었습니다.

 

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

사용자의 브라우저 주소 경로에 따라 우리가 원하는 컴포넌트를 보여주려면 Route라는 컴포넌트를 통해 라우트 설정을 해주어야 합니다.

Route 컴포넌트는 다음과 같이 사용합니다.

<Route path="주소규칙" element={보여 줄 컴포넌트 JSX} />

App 컴포넌트에서 Route 컴포넌트를 사용하여 다음과 같이 라우트를 설정합니다.

// src/App.js

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;

이제 yarn start를 입력하여 개발 서버를 시작하면 첫 화면에 Home 컴포넌트가 나타납니다.

 

 

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

Link 컴포넌트를 사용하면 다른 페이지로 이동하는 링크입니다. a 태그를 이용하여 웹 페이지의 링크를 부르면 페이지를 새로 불러오기 때문에 서버 리소스를 사용하게 됩니다. Link 컴포넌트를 사용하면 페이지를 새로 불러오는 것을 막고 History API를 통해 브라우저 주소의 경로만 바꿀 수 있습니다.

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

 

Home 페이지에서 About 페이지로 이동할 수 있도록 Link 컴포넌트를 Home 페이지 컴포넌트에서 사용합니다.

// src/pages/Home.js
import { Link } from 'react-router-dom';

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

export default Home;

 

IV. URL 파라미터와 쿼리스트링

 페이지 주소를 정의할 때 가끔은 유동적인 값을 사용해야 할  때 두 가지 방법 중 하나로 사용합니다.

  • URL 파라미터 예시: /profile/corner
  • 주소의 경로에 유동적인 값을 넣는 형태
  •  주로 ID 또는 이름을 사용하여 특정 데이터를 조회할 때 사용

 

  • 쿼리스트링 예시: /articles?page=1&keword=react
  • 주소의 뒷부분에 ? 문자열 이후에 key=value로 값을 정의하며 &로 구분하는 형태
  • 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용

 

1. URL 파라미터

 우선 URL 파라미터를 사용하는 방법을 알아보기 위해 새로운 페이지 컴포넌트를 만들겠습니다. pages 경로에 다음과 같이 Profile 컴포넌트를 작성합니다.

// src/pages/Profile.js

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

const data = {
  corner: {
    name: '코너',
    description: '리액트를 좋아하는 개발자',
  },
  gildong: {
    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;
  • URL 파라미터는 useParams라는 Hook을 사용하여 객체 형태로 조회
  • URL 파라미터의 이름은 라우트 설정할 때 Route 컴포넌트의 path props를 통해 설정합니다.
  • data 객체에 예시 프로필 정보들을 key-value 형태로 담아두었습니다.
  • Profile 컴포넌트에서는 usename URL 파라미터를 통하여 프로필을 조회한 뒤에 프로필이 존재하지 않으면 '존재하지 않는 프로필입니다.'라는 문구를 보여줍니다.

 

이후 App 컴포넌트에 새로운 라우트를 다음과 같이 설정합니다.

// src/App.js
( ... )
import Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      ( ... )
      <Route path="/profiles/:username" element={<Profile />}/>
    </Routes>
  );
};
  • URL 파라미터는 /profiles/:username과 같이 경로에 :를 사용하여 설정
  • 만약 URL 파라미터가 여러 개인 경우에는 /profiles/:username/:field와 같은 형태로 설정

이제 Profile 페이지로 이동할 수 있도록 Home 페이지에 Link를 더 만들고 ul 태그를 사용하여 리스트 형태로 보입니다.

// src/pages/Home.js
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/corner">corner의 프로필</Link>
        </li>
        <li>
          <Link to="/profiles/gildong">gildong의 프로필</Link>
        </li>
        <li>
          <Link to="/profiles/void">존재하지 않는 프로필</Link>
        </li>
      </ul>
    </div>
  );
};

export default Home;

 

2. 쿼리스트링

라우트에서 쿼리스트링을 사용하는 방법을 알아봅시다. 쿼리스트링을 사용할 때는 URL 파라미터와 달리 Route 컴포넌트를 사용할 때 별도로 설정해야 하는 것이 없습니다.

 

우선 쿼리스트링을 화면에 띄워보기 위해 About 페이지 컴포넌트를 다음과 같이 수정합니다.

// src/pages/About.js
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;
  • useLocation이라는 Hook을 사용해 location 객체를 반환받음
  • 이 객체는 현재 사용자가 보고 있는 페이지의 정보를 지님
    • pathname: 현재 주소의 경로
    • search: 맨 앞의 ? 문자를 포함한 쿼리스트링 값
    • hash: 주소의 # 문자열 뒤의 값, 주로 History API가 지원되지 않는 구형 브라우저에서 클라이언트 라우팅을 사용할 때 쓰는 해시 라우터에서 사용
    • state: 페이지로 이동할 때 임의로 넣을 수 있는 상태 값
    • key: location 객체의 고유 값, 초기에는 default이며 페이지가 변경될 때마다 고유의 값이 생성됨
  • 쿼리스트링은 location.search 값을 통해 조회할 수 있음

 주소창에 http://localhost:3000/about?detail=true&mode=1라고 직접 입력해서 어떤 값이 나타나는지 확인해보세요.

리액트 라우터에서는 v6부터 useSearchParams라는 Hook을 통해서 쿼리스트링을 쉽게 다룰 수 있습니다.

 

다음은 이 Hook을 사용해 쿼리스트링을 쉽게 파싱하여 사용하는 예시입니다.

// src/pages/About.js
import { useSearchParams } from 'react-router-dom';

const About = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const detail = searchParams.get('detail');
  const mode = searchParams.get('mode');

  const onToggleDetail = () => {
    setSearchParams({ mode, detail: detail === 'true' ? false : true });
  };

  const onIncreaseMode = () => {
    const nextMode = mode === null ? 1: parseInt(mode) + 1;
    setSearchParams({ mode: nextMode, detail });
  };

  return (
    <div>
      <h1>소개</h1>
      <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
      <p>detail: {detail}</p>
      <button onClick={onToggleDetail}>Toggle detail</button>
      <button onClick={onIncreaseMode}>mode + 1</button>
    </div>
  );
};

export default About;
  • useSearchParams는 배열 타입의 값을 반환
  • 첫 번째 원소는 쿼리파라미터를 조회하거나 수정하는 메서드들이 담긴 객체를 반환
  • get 메서드를 통해 특정 쿼리파라미터를 조회할 수 있고, set 메서드를 통해 특정 쿼리파라미터를 업데이트
  • 조회 시 쿼리파라미터가 존재하기 않는다면 null로 조회
  • 두 번째 원소는 쿼리 파라미터를 객체 형태로 업데이트할 수 있는 함수를 반환합니다.

 

V. 중첩된 라우트

중첩된 라우트를 이해하기 위해, 게시글 목록을 보여주는 페이지와 게시글을 읽는 페이지를 만들어보겠습니다. 

// src/pages/Articles.js

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

const Articles = () => {
  return (
    <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>
  );
};

export default Articles;
// src/pages/Article.js

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

const Article = () => {
  const { id } = useParams();
  return (
    <div>
      <h2>게시글 {id}</h2>
    </div>
  );
};

export default Article;

 두 컴포넌트를 만든 다음 App 컴포넌트에서 해당 페이지들의 라우트를 설정합니다.

// src/App.js

( ... )
      <Route path="/articles" element={<Articles />}/>
      <Route path="/articles/:id" element={<Article />}/>
    </Routes>
  );
};

export default App;

그다음 Home 컴포넌트에서 게시글 목록 페이지로 가는 링크를 추가합니다.

// src/pages/Home.js 에 추가

<li>
  <Link to="/articles">게시글 목록</Link>
</li>

 

게시글을 열었을 때, 게시글 하단에 목록을 보여주려고 한다면 중첩된 라우트 형태로 라우트를 설정하면 손쉽게 구현할 수 있습니다.

App 컴포넌트를 다음과 같이 수정합니다.

// src/App.js
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="/articles" element={<Articles />}>
        <Route path=":id" element={<Article />}/>
      </Route>
    </Routes>
  );
};

export default App;
  • 다음으로 Articles 컴포넌트에 리액트 라우터에서 제공하는 Outlet이라는 컴포넌트를 사용
  • 컴포넌트는 Route의 children으로 들어가는 JSX 엘리먼트를 보여주는 역할을

Articles 컴포넌트를 다음과 같이 수정합니다.

// src/pages/Articles.js
import {Link, Outlet} from 'react-router-dom';

const Articles = () => {
  return (
    <div>
      <Outlet />
      <ul>
        (...)
      </ul>
    </div>
  );
};

export default Articles;

위 코드에서 Outlet 컴포넌트가 사용된 자리에 중첩된 라우트가 보이게 됩니다. 다음 사진은 /articles/1 경로로 들어간 것입니다.

 

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

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

예를 들어 Home, About, Profile 페이지 상단에 헤더를 보여줘야 하는 상황을 가정해보겠습니다. 가장 먼저 Header 컴포넌트를 따로 만들어두고 각 페이지 컴포넌트에서 재사용하는 방법을 생각할 것입니다. 그러나 이 방법보다는 컴포넌트를 한 번만 사용해도록 방금 배운 중첩된 라우트와 Outlet을 활용하여 구현할 수도 있습니다.

 

이번에는 중첩된 라우트를 통해 공통 레이아웃 컴포넌트인 Layout 컴포넌트를 src 디렉터리에 만듭니다.

// src/Layout.js

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;

각 페이지 컴포넌트가 보여야 하는 부분에 Outlet 컴포넌트를 사용해줍니다.

// src/App.js
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;

 

2. index props

 Route 컴포넌트에는 index라는 props가 있습니다. 이 props는 path="/"와 동일한 의미를 가집니다.

// src/App.js
(...)

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Layout />}>
        <Route index element={<Home />}/>
       (...)
  );
};

export default App;
  • index props를 사용하면 상위 라우트의 경로와 일치하지만,  이후에 경로가 주어지지 않았을 때 보이는 라우트를 설정
  • path="/"와 동일한 역할을 하며 이를 좀 더 명시적으로 표현하는 방법입니다.

 

VI. 리액트 부가 기능

리액트 라우터는 웹 애플리케이션에서 라우팅과 관련된 작업을 할 때 사용할 수 있는 유용한 API들을 제공합니다. 자주 사용되는 것들을 알아봅시다.

 

1. useNavigate

 useNavigate Link 컴포넌트를 사용하지 않고 다른 페이지로 이동해야 하는 상황에 사용하는 Hook입니다. 

// src/Layout.js
import { Outlet, useNavigate } from 'react-router-dom';

const Layout = () => {
  const navigate = useNavigate();

  const goBack = () => {
    // 이전 페이지로 이동
    navigate(-1);
  };

  const goArticles = () => {
    // articles 경로로 이동
    navigate('/articles');
  };

  return (
    <div>
      <header style={{ background: 'lightgray', padding: 16, fontsize: 24 }}>
        <button onClick={goBack}>뒤로 가기</button>
        <button onClick={goArticles}>게시글 목록</button>
      </header>
      <main>
        <Outlet />
      </main>
    </div>
  );
};

export default Layout;

 

  • navigate 함수를 사용할 때 파라미터가 숫자 타입이라면 앞으로 가거나, 뒤로 갑니다.

다른 페이지로 이동할 때 replace라는 옵션이 있는데, 이 옵션을 사용하면 페이지를 이동할 때 현재 페이지를 페이지 기록에 남기지 않습니다.

 

2. NavLink

NavLink 컴포넌트는 링크에서 사용하는 경로가 현재 라우트의 경로와 일치하는 경우 특정 스타일 또는 CSS 클래스를 적용하는 컴포넌트입니다.

만약 위의 컴포넌트를 사용하지 않는다면 반복되는 코드를 작성해야할 것입니다. 현재 NavLink를 감싼 또 다른 컴포넌트를 만들어서 다음과 같이 리펙터링하여 사용하는 것을 권장합니다.

// src/pages/Articles.js
import {NavLink, Outlet} from 'react-router-dom';

const Articles = () => {
  return (
    <div>
      <Outlet />
      <ul>
        <ArticleItem id={1} />
        <ArticleItem id={2} />
        <ArticleItem id={3} />
      </ul>
    </div>
  );
};

const ArticleItem =({ id }) => {
  const activeStyle = {
    color: 'green',
    fontSize: 21,
  };
  return (
    <li>
      <NavLink 
        to={`/articles/${id}`}
        style={({ isActive }) => (isActive ? activeStyle : undefined)}
      >
        게시글 {id}
      </NavLink>
    </li>  
  );
};

export default Articles;

 

3. NotFound 페이지 만들기

이번에는 NotFound 페이지를 만드는 방법을 배우겠습니다. 이 페이지는 사전에 정의되지 않는 경로에 사용자가 진입했을 때 보여주는 페이지입니다. 

// src/pages/NotFound.js
const NotFound = () => {
  return (
    <div
      style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: 64,
        position: 'absolute',
        width: '100%',
        height: '100%',
      }}
    >
      404
    </div>
  );
};

export default NotFound;

그다음 App 컴포넌트를 수정합니다.

// src/App.js
(...)
import NotFound from './pages/NotFound';

const App = () => {
  return (
    <Routes>
      (...)
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
};

export default App;
  •  *는 wildcard 문자로, 아무 텍스트나 매칭한다는 뜻
  • 라우트 엘리먼트의 상단에 위치하는 라우트들의 규칙을 모두 확인하고, 일치하는 라우트가 없다면 이 라우트가 화면에 나타남

 

4. Navigate 컴포넌트 

 Navigate 컴포넌트는 컴포넌트를 화면에 보여주는 순간 다른 페이지로 이동하고 싶을 때 사용하는 컴포넌트입니다.

예를 들어 사용자의 로그인이 필요한 페이지인데 로그인을 안 했다면 로그인 페이지를 보여줘야할 때 사용할 수 있습니다.

// src/pages/Login.js
const Login = () => {
  return <div>로그인 페이지</div>;
};

export default Login;
// src/pages/MyPage.js
import { Navigate } from 'react-router-dom';

const MyPage = () => {
  const isLoggedIn = false;

  if(!isLoggedIn){
    return <Navigate to="/login" replace={true} />;
  }

  return <div>마이 페이지</div>;
}

export default MyPage;

다음으로 App 컴포넌트를 수정합니다.

// src/App.js
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 Login from './pages/Login';
import MyPage from './pages/MyPage';
import NotFound from './pages/NotFound';
import Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Layout />}>
        <Route index 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>
      <Route path="/login" element={<Login />} />
      <Route path="/mypage" element={<MyPage />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
};

export default App;

이제 브라우저 주소창에 /mypage 경로를 직접 입력해 들어가 봅니다. 페이지가 로딩되는 순간 바로 Login 페이지로 이동됩니다.

 

Quiz

  1. 사용자가 요청한 URL에 따라 알맞은 페이지를 보여주는 것을 (____)이라고 합니다.
  2. (____)는 리액트에서 라우팅 시스템을 구현하기 위해 필요한 라이브러리로, 가장 오래되고 많이 사용됩니다.
  3. (____)은 하나의 페이지로 이루어진 애플리케이션으로 새로운 데이터가 필요하면 서버 API를 호출하여 사용합니다.
  4. Route 컴포넌트는 다음과 같이 작성됩니다. <Route path="주소규칙" (____)={보여줄 컴포넌트 JSX}>
  5. Link 컴포넌트는 다음과 같이 사용됩니다. <Link (____)="경로">링크 이름</Link>
  6. 유동적인 값으로 페이지 주소를 정의하는 두 가지 방법은 (____)과 (____)이 있습니다.
  7. 리액트에서 중첩된 라우트를 사용하기 위해서는 (____) 컴포넌트를 사용합니다.
  8. src/Layout.js에서 replace 함수를 사용하여 페이지를 이동해보도록 하는 함수를 작성하세요
  9. App.js에 로그인 컴포넌트를 포함하여 라우트 하는 코드를 작성해보세요.

 

Answer

  1. 라우팅
  2. 리액트 라우터
  3. 싱글 페이지 애플리케이션
  4. element
  5. to
  6. URL 파라미터, 쿼리스트링
  7. Outlet
  8.  
const goArticles = () => {
   navigate('articles', { replace: true });
}

9.

// App.js

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 Login from './pages/Login'
import MyPage from './pages/MyPage';
import NotFound from './pages/NotFound';
import Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      <Route path='/' element={<Layout />}>
        <Route index element={<Home />} />
        <Route path='/about' element={<About />} />
        <Route path='/profile/:username' element={<Profile />} />
      </Route>
      <Route path='/articles' element={<Articles />}>
        <Route path=':id' element={<Article />} />
      </Route>
      <Route path='/login' element={<Login />} />
      <Route path='/mypage' element={<MyPage />} />
      <Route path='*' element={<NotFound />} />
    </Routes>
  );
};

export default App;
728x90

관련글 더보기