React - Router

김명원·2025년 1월 7일
0

learnReact

목록 보기
12/26

React Router

React Router란?

React Router는 React 애플리케이션에서 클라이언트 측 라우팅을 관리하는 라이브러리입니다. 이를 통해 사용자가 애플리케이션 내에서 페이지 간에 원활하게 이동할 수 있도록 도와줍니다. React Router를 사용하면 페이지 리로드 없이도 다양한 컴포넌트를 렌더링할 수 있어 사용자 경험을 향상시킬 수 있습니다.


강의 개요

  • React Router의 기본 개념 이해
  • 설치 및 설정 방법
  • 라우팅 기본 설정 실습
  • 동적 라우팅 및 중첩 라우트
  • 네비게이션 링크 사용하기
  • 라우트 보호 (Protected Routes)
  • 추가 기능 및 고급 사용법

라우팅이란?

라우팅(Routing)은 웹사이트에서 사용자가 어떤 페이지로 이동할지를 결정하는 과정입니다. 이는 마치 책의 목차처럼, 사용자가 특정 링크를 클릭하면 해당 내용으로 이동할 수 있게 하는 역할을 합니다.

예시

블로그 웹사이트를 생각해보세요. 다음과 같은 페이지가 있을 수 있습니다:

  • 홈페이지 (/home)
  • 글 목록 페이지 (/posts)
  • 글 상세보기 페이지 (/posts/:id)

사용자가 "홈" 버튼을 클릭하면 홈페이지 내용이, "글 목록"을 클릭하면 글 목록이 나타나고, 특정 글을 클릭하면 해당 글의 상세 내용이 표시됩니다.

React Router를 사용하면 이러한 페이지 간의 이동을 손쉽게 관리할 수 있습니다.


클라이언트 측 라우팅이란?

클라이언트 측 라우팅(Client-side Routing)은 브라우저에서 자바스크립트를 사용하여 페이지 간의 전환을 관리하는 방식입니다. 이는 전체 페이지를 다시 로드하지 않고도 사용자 인터페이스를 업데이트할 수 있어 빠르고 부드러운 사용자 경험을 제공합니다.

서버 측 라우팅과의 차이점

  • 서버 측 라우팅: 사용자가 새로운 페이지를 요청할 때마다 서버가 전체 페이지를 렌더링하여 응답합니다.
  • 클라이언트 측 라우팅: 초기 페이지 로드 이후, 자바스크립트를 통해 필요한 부분만 업데이트하여 페이지를 전환합니다.

React Router 설치

React Router를 프로젝트에 설치하려면 다음 명령어를 사용하세요:

npm install react-router-dom
npm install react-icons --save

또는

yarn add react-router-dom react-icons

실습 - React Router 설정

1. 프로젝트 초기 설정

먼저, React 프로젝트의 진입점 파일인 src/main.jsx를 수정하여 React Router를 설정합니다.

src/main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import './index.css';
import App from './App';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';

// 라우터 설정
const router = createBrowserRouter([
  {
    path: '/',
    element: <App />, // 공통 레이아웃 컴포넌트
    children: [
      {
        path: '/',
        element: <Home />, // 홈 페이지
      },
      {
        path: 'about',
        element: <About />, // 소개 페이지
      },
      {
        path: 'contact',
        element: <Contact />, // 연락처 페이지
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
);

2. 라우팅 레이아웃 구성

src/App.jsx

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

function App() {
  return (
    <>
      <nav className="navbar">
        <ul className="nav-links">
          <li>
            <Link to="/"></Link>
          </li>
          <li>
            <Link to="/about">소개</Link>
          </li>
          <li>
            <Link to="/contact">연락처</Link>
          </li>
        </ul>
      </nav>
      <main>
        <Outlet /> {/* 자식 라우트가 렌더링되는 위치 */}
      </main>
    </>
  );
}

export default App;

3. 페이지 컴포넌트 생성

각 페이지별 컴포넌트를 생성하여 라우터 설정에 맞게 렌더링합니다.

src/pages/Home.jsx

function Home() {
  return <div>홈 페이지에 오신 것을 환영합니다!</div>;
}

export default Home;

src/pages/About.jsx

function About() {
  return <div>소개 페이지입니다.</div>;
}

export default About;

src/pages/Contact.jsx

function Contact() {
  return <div>연락처 페이지입니다.</div>;
}

export default Contact;

4. 네비게이션 스타일링 (선택 사항)

더 나은 사용자 경험을 위해 네비게이션 바를 스타일링할 수 있습니다. 예를 들어, src/index.css 파일에 다음과 같은 스타일을 추가할 수 있습니다:

src/index.css

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

.navbar {
  background-color: #333;
  padding: 1rem;
}

.nav-links {
  list-style: none;
  display: flex;
  gap: 1rem;
}

.nav-links li a {
  color: white;
  text-decoration: none;
}

.nav-links li a:hover {
  text-decoration: underline;
}

main {
  padding: 2rem;
}

주요 개념 설명

1. <BrowserRouter>

<BrowserRouter>는 HTML5의 History API를 사용하여 URL을 관리합니다. 이를 통해 URL이 변경될 때마다 페이지를 새로고침하지 않고도 React 컴포넌트를 업데이트할 수 있습니다.

2. <Routes><Route>

  • <Routes>: 여러 개의 <Route>를 감싸고, URL 경로에 따라 적절한 <Route>를 렌더링합니다.
  • <Route>: 특정 경로에 매칭되는 컴포넌트를 정의합니다.

<Link> 컴포넌트는 사용자 인터페이스에서 페이지 간의 이동을 가능하게 합니다. <a> 태그와 유사하지만, 전체 페이지를 다시 로드하지 않고 클라이언트 측 라우팅을 통해 이동합니다.

4. <Outlet>

<Outlet>은 중첩된 라우트의 컴포넌트를 렌더링하는 자리 표시자입니다. 부모 라우트의 레이아웃 내에서 자식 라우트의 내용을 표시할 위치를 지정합니다.


고급 기능

1. 동적 라우팅

동적 라우팅을 사용하면 URL 파라미터를 기반으로 동적으로 데이터를 로드할 수 있습니다.

예시: 글 상세 페이지

src/pages/Post.jsx

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

function Post() {
  const { id } = useParams(); // URL 파라미터 추출
  return <div>글 상세보기 페이지입니다.ID: {id}</div>;
}

export default Post;

라우터 설정 업데이트

src/main.jsx

import Post from './pages/Post';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
      {
        path: 'contact',
        element: <Contact />,
      },
      {
        path: 'post/:id', // 동적 경로
        element: <Post />,
      },
    ],
  },
]);

2. 네스티드 라우팅

네스티드 라우팅을 사용하면 복잡한 레이아웃을 구성하고, 각 레이아웃 내에서 다른 라우트를 정의할 수 있습니다.

예시: 대시보드 레이아웃

src/App.jsx

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

function App() {
  return (
    <>
      <nav className="navbar">
        <ul className="nav-links">
          <li>
            <Link to="/"></Link>
          </li>
          <li>
            <Link to="/dashboard">대시보드</Link>
          </li>
        </ul>
      </nav>
      <main>
        <Outlet />
      </main>
    </>
  );
}

export default App;

대시보드 컴포넌트와 라우팅 설정

src/pages/Dashboard.jsx

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

function Dashboard() {
  return (
    <div>
      <h2>대시보드</h2>
      <ul>
        <li>
          <Link to="analytics">분석</Link>
        </li>
        <li>
          <Link to="settings">설정</Link>
        </li>
      </ul>
      <Outlet /> {/* 대시보드 내의 자식 라우트 */}
    </div>
  );
}

export default Dashboard;

라우터 설정 업데이트

src/main.jsx

import Dashboard from './pages/Dashboard';
import Analytics from './pages/Analytics';
import Settings from './pages/Settings';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
      {
        path: 'contact',
        element: <Contact />,
      },
      {
        path: 'dashboard',
        element: <Dashboard />,
        children: [
          {
            path: 'analytics',
            element: <Analytics />,
          },
          {
            path: 'settings',
            element: <Settings />,
          },
        ],
      },
    ],
  },
]);

src/pages/Analytics.jsx

function Analytics() {
  return <div>분석 페이지입니다.</div>;
}

export default Analytics;

src/pages/Settings.jsx

function Settings() {
  return <div>설정 페이지입니다.</div>;
}

export default Settings;

3. 라우트 보호 (Protected Routes)

특정 라우트에 접근하기 위해서는 인증이 필요할 때 라우트 보호 기능을 사용할 수 있습니다.

예시: 로그인된 사용자만 접근 가능한 대시보드

src/ProtectedRoute.jsx

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

function ProtectedRoute({ isAuthenticated, children }) {
  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }
  return children;
}

export default ProtectedRoute;

라우터 설정 업데이트

src/main.jsx

import ProtectedRoute from './ProtectedRoute';
import Login from './pages/Login';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
      {
        path: 'contact',
        element: <Contact />,
      },
      {
        path: 'login',
        element: <Login />,
      },
      {
        path: 'dashboard',
        element: (
          <ProtectedRoute isAuthenticated={true}> {/* 인증 상태에 따라 변경 */}
            <Dashboard />
          </ProtectedRoute>
        ),
        children: [
          {
            path: 'analytics',
            element: <Analytics />,
          },
          {
            path: 'settings',
            element: <Settings />,
          },
        ],
      },
    ],
  },
]);

src/pages/Login.jsx

function Login() {
  return <div>로그인 페이지입니다.</div>;
}

export default Login;

실습 요약

React Router 설정 단계

  1. React Router 설치

    npm install react-router-dom react-icons --save
  2. 라우터 설정 (src/main.jsx)

    • createBrowserRouterRouterProvider를 사용하여 라우터를 설정
    • 라우트 경로와 렌더링할 컴포넌트를 정의
  3. 레이아웃 컴포넌트 생성 (src/App.jsx)

    • 네비게이션 바와 <Outlet>을 사용하여 자식 라우트를 렌더링할 위치 지정
  4. 페이지 컴포넌트 생성 (src/pages/)

    • Home.jsx, About.jsx, Contact.jsx 등의 컴포넌트 생성
  5. 네비게이션 링크 추가 (<Link> 컴포넌트 사용)

    • 사용자 인터페이스에서 페이지 간 이동을 가능하게 함
  6. 고급 기능 실습

    • 동적 라우팅, 네스티드 라우팅, 라우트 보호 등

추가 자료

React Router의 더 자세한 내용과 고급 기능에 대해서는 공식 문서를 참고하세요:


결론

React Router는 React 애플리케이션에서 클라이언트 측 라우팅을 효과적으로 관리할 수 있게 해주는 필수적인 라이브러리입니다. 이를 통해 사용자 경험을 향상시키고, 애플리케이션의 구조를 체계적으로 관리할 수 있습니다. 기본적인 라우팅 설정부터 고급 기능까지 익히면서 React 프로젝트에 적용해보세요. 꾸준한 실습과 공식 문서 참고를 통해 더욱 깊이 있는 이해를 도모할 수 있습니다.


React Router 심화 학습


React Router란?

React Router는 React 애플리케이션에서 클라이언트 측 라우팅을 관리하는 필수적인 라이브러리입니다. 이를 통해 사용자는 페이지를 새로고침하지 않고도 애플리케이션 내에서 다양한 페이지로 원활하게 이동할 수 있습니다. React Router는 SPA(Single Page Application)의 핵심 요소로, 사용자 경험을 크게 향상시킵니다.


라우팅이란?

라우팅(Routing)은 사용자가 웹 애플리케이션 내에서 특정 페이지나 뷰로 이동할 수 있도록 경로를 설정하는 과정입니다. 이는 웹사이트의 목차와 유사하게, 사용자가 특정 링크를 클릭하면 해당 링크에 맞는 내용이 표시되도록 합니다.

예시

블로그 웹사이트를 예로 들어보겠습니다. 다음과 같은 페이지가 있을 수 있습니다:

  • 홈페이지 (/home)
  • 글 목록 페이지 (/posts)
  • 글 상세보기 페이지 (/posts/:id)

사용자가 "홈" 버튼을 클릭하면 홈페이지 내용이, "글 목록"을 클릭하면 글 목록이 나타나며, 특정 글을 클릭하면 해당 글의 상세 내용이 표시됩니다. React Router를 사용하면 이러한 페이지 간의 이동을 손쉽게 관리할 수 있습니다.


클라이언트 측 라우팅

클라이언트 측 라우팅(Client-side Routing)은 브라우저에서 자바스크립트를 사용하여 페이지 간의 전환을 관리하는 방식입니다. 이는 전체 페이지를 다시 로드하지 않고도 사용자 인터페이스를 업데이트할 수 있어 빠르고 부드러운 사용자 경험을 제공합니다.

서버 측 라우팅과의 차이점

  • 서버 측 라우팅(Server-side Routing):
    • 사용자가 새로운 페이지를 요청할 때마다 서버가 전체 페이지를 렌더링하여 응답합니다.
    • 예: 전통적인 멀티 페이지 애플리케이션(MPA)
  • 클라이언트 측 라우팅(Client-side Routing):
    • 초기 페이지 로드 이후, 자바스크립트를 통해 필요한 부분만 업데이트하여 페이지를 전환합니다.
    • 예: 싱글 페이지 애플리케이션(SPA)

React Router 설치

React Router를 프로젝트에 설치하려면 다음 명령어를 사용하세요:

npm install react-router-dom
npm install react-icons --save

또는

yarn add react-router-dom react-icons

실습 - React Router 설정

1. 프로젝트 초기 설정

먼저, React 프로젝트의 진입점 파일인 src/main.jsx를 수정하여 React Router를 설정합니다.

src/main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import './index.css';
import App from './App';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />, // 공통 레이아웃 컴포넌트
    children: [
      {
        path: '/',
        element: <Home />, // 홈 페이지
      },
      {
        path: 'about',
        element: <About />, // 소개 페이지
      },
      {
        path: 'contact',
        element: <Contact />, // 연락처 페이지
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
);

2. 라우팅 레이아웃 구성

src/App.jsx

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

function App() {
  return (
    <>
      <nav className="navbar">
        <ul className="nav-links">
          <li>
            <Link to="/"></Link>
          </li>
          <li>
            <Link to="/about">소개</Link>
          </li>
          <li>
            <Link to="/contact">연락처</Link>
          </li>
        </ul>
      </nav>
      <main>
        <Outlet /> {/* 자식 라우트가 렌더링되는 위치 */}
      </main>
    </>
  );
}

export default App;

3. 페이지 컴포넌트 생성

각 페이지별 컴포넌트를 생성하여 라우터 설정에 맞게 렌더링합니다.

src/pages/Home.jsx

function Home() {
  return <div>홈 페이지에 오신 것을 환영합니다!</div>;
}

export default Home;

src/pages/About.jsx

function About() {
  return <div>소개 페이지입니다.</div>;
}

export default About;

src/pages/Contact.jsx

function Contact() {
  return <div>연락처 페이지입니다.</div>;
}

export default Contact;

4. 네비게이션 스타일링 (선택 사항)

더 나은 사용자 경험을 위해 네비게이션 바를 스타일링할 수 있습니다. 예를 들어, src/index.css 파일에 다음과 같은 스타일을 추가할 수 있습니다:

src/index.css

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

.navbar {
  background-color: #333;
  padding: 1rem;
}

.nav-links {
  list-style: none;
  display: flex;
  gap: 1rem;
}

.nav-links li a {
  color: white;
  text-decoration: none;
}

.nav-links li a:hover {
  text-decoration: underline;
}

main {
  padding: 2rem;
}

주요 개념 설명

<BrowserRouter>

<BrowserRouter>는 HTML5의 History API를 사용하여 URL을 관리합니다. 이를 통해 URL이 변경될 때마다 페이지를 새로고침하지 않고도 React 컴포넌트를 업데이트할 수 있습니다.

<Routes><Route>

  • <Routes>: 여러 개의 <Route>를 감싸고, URL 경로에 따라 적절한 <Route>를 렌더링합니다.
  • <Route>: 특정 경로에 매칭되는 컴포넌트를 정의합니다.

<Link> 컴포넌트는 사용자 인터페이스에서 페이지 간의 이동을 가능하게 합니다. <a> 태그와 유사하지만, 전체 페이지를 다시 로드하지 않고 클라이언트 측 라우팅을 통해 이동합니다.

<NavLink><Link>와 유사하지만, 현재 활성화된 링크에 특정 스타일을 적용할 수 있는 기능을 제공합니다. 이를 통해 사용자가 현재 어느 페이지에 있는지 시각적으로 알 수 있습니다.

사용 예시:

<NavLink
  to="/about"
  className={({ isActive }) => (isActive ? 'active-link' : '')}
>
  About
</NavLink>

CSS:

.active-link {
  color: blue;
  font-weight: bold;
}

<Outlet>

<Outlet>은 중첩된 라우트의 컴포넌트를 렌더링하는 자리 표시자입니다. 부모 라우트의 레이아웃 내에서 자식 라우트의 내용을 표시할 위치를 지정합니다.

useNavigate

useNavigate는 프로그래밍 방식으로 라우트를 변경할 수 있게 해주는 훅입니다. 예를 들어, 버튼 클릭 시 특정 페이지로 이동하고 싶을 때 유용하게 사용됩니다.

사용 예시:

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

function Header() {
  const navigate = useNavigate();
  
  return (
    <header>
      <button onClick={() => navigate('/')}>홈으로 이동</button>
    </header>
  );
}

고급 기능

1. 동적 라우팅

동적 라우팅을 사용하면 URL 파라미터를 기반으로 동적으로 데이터를 로드할 수 있습니다.

예시: 글 상세 페이지

src/pages/Post.jsx

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

function Post() {
  const { id } = useParams(); // URL 파라미터 추출
  return <div>글 상세보기 페이지입니다.ID: {id}</div>;
}

export default Post;

라우터 설정 업데이트

src/main.jsx

import Post from './pages/Post';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
      {
        path: 'contact',
        element: <Contact />,
      },
      {
        path: 'post/:id', // 동적 경로
        element: <Post />,
      },
    ],
  },
]);

2. 네스티드 라우팅

네스티드 라우팅을 사용하면 복잡한 레이아웃을 구성하고, 각 레이아웃 내에서 다른 라우트를 정의할 수 있습니다.

예시: 대시보드 레이아웃

src/App.jsx

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

function App() {
  return (
    <>
      <nav className="navbar">
        <ul className="nav-links">
          <li>
            <Link to="/"></Link>
          </li>
          <li>
            <Link to="/dashboard">대시보드</Link>
          </li>
        </ul>
      </nav>
      <main>
        <Outlet />
      </main>
    </>
  );
}

export default App;

대시보드 컴포넌트와 라우팅 설정

src/pages/Dashboard.jsx

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

function Dashboard() {
  return (
    <div>
      <h2>대시보드</h2>
      <ul>
        <li>
          <Link to="analytics">분석</Link>
        </li>
        <li>
          <Link to="settings">설정</Link>
        </li>
      </ul>
      <Outlet /> {/* 대시보드 내의 자식 라우트 */}
    </div>
  );
}

export default Dashboard;

라우터 설정 업데이트

src/main.jsx

import Dashboard from './pages/Dashboard';
import Analytics from './pages/Analytics';
import Settings from './pages/Settings';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
      {
        path: 'contact',
        element: <Contact />,
      },
      {
        path: 'dashboard',
        element: <Dashboard />,
        children: [
          {
            path: 'analytics',
            element: <Analytics />,
          },
          {
            path: 'settings',
            element: <Settings />,
          },
        ],
      },
    ],
  },
]);

src/pages/Analytics.jsx

function Analytics() {
  return <div>분석 페이지입니다.</div>;
}

export default Analytics;

src/pages/Settings.jsx

function Settings() {
  return <div>설정 페이지입니다.</div>;
}

export default Settings;

3. 라우트 보호 (Protected Routes)

특정 라우트에 접근하기 위해서는 인증이 필요할 때 라우트 보호 기능을 사용할 수 있습니다.

예시: 로그인된 사용자만 접근 가능한 대시보드

src/ProtectedRoute.jsx

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

function ProtectedRoute({ isAuthenticated, children }) {
  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }
  return children;
}

export default ProtectedRoute;

라우터 설정 업데이트

src/main.jsx

import ProtectedRoute from './ProtectedRoute';
import Login from './pages/Login';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
      {
        path: 'contact',
        element: <Contact />,
      },
      {
        path: 'login',
        element: <Login />,
      },
      {
        path: 'dashboard',
        element: (
          <ProtectedRoute isAuthenticated={true}> {/* 인증 상태에 따라 변경 */}
            <Dashboard />
          </ProtectedRoute>
        ),
        children: [
          {
            path: 'analytics',
            element: <Analytics />,
          },
          {
            path: 'settings',
            element: <Settings />,
          },
        ],
      },
    ],
  },
]);

src/pages/Login.jsx

function Login() {
  return <div>로그인 페이지입니다.</div>;
}

export default Login;

1. navigate() 사용법

useNavigate 훅을 사용하면 프로그래밍 방식으로 라우트를 변경할 수 있습니다. 이는 버튼 클릭 시 특정 페이지로 이동하고 싶을 때 유용하게 사용됩니다.

src/components/Header.jsx

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

function Header() {
  const navigate = useNavigate();
  return (
    <header>
      <ul>
        {/* 프로그래밍 방식으로 라우팅 */}
        <li onClick={() => navigate('/')}>Home</li>
        <li onClick={() => navigate('/about')}>About</li>
        <li onClick={() => navigate('/contact')}>Contact</li>
        
        {/* <Link> 컴포넌트를 사용한 라우팅 */}
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/contact">Contact</Link>
        </li>
      </ul>
    </header>
  );
}

export default Header;

<NavLink>는 현재 활성화된 링크에 특정 스타일을 적용할 수 있는 기능을 제공합니다. 이를 통해 사용자가 현재 어느 페이지에 있는지 시각적으로 알 수 있습니다.

src/components/Header.jsx

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

function Header() {
  const navigate = useNavigate();
  return (
    <header>
      <ul>
        {/* 프로그래밍 방식으로 라우팅 */}
        {/* <li onClick={() => navigate('/')}>Home</li>
        <li onClick={() => navigate('/about')}>About</li>
        <li onClick={() => navigate('/contact')}>Contact</li> */}
        
        {/* <NavLink> 컴포넌트를 사용한 라우팅 */}
        <li>
          <NavLink
            to="/"
            className={({ isActive }) => (isActive ? 'text-blue-700' : '')}
          >
            Home
          </NavLink>
        </li>
        <li>
          <NavLink
            to="/about"
            className={({ isActive }) => (isActive ? 'text-blue-700' : '')}
          >
            About
          </NavLink>
        </li>
        <li>
          <NavLink
            to="/contact"
            className={({ isActive }) => (isActive ? 'text-blue-700' : '')}
          >
            Contact
          </NavLink>
        </li>
      </ul>
    </header>
  );
}

export default Header;

CSS (src/index.css)

.text-blue-700 {
  color: #2b6cb0;
  font-weight: bold;
}

실습 - ErrorPage 구현

애플리케이션에서 사용자가 잘못된 경로로 접근했을 때 보여줄 에러 페이지를 구현할 수 있습니다. 이를 통해 사용자에게 친절한 안내를 제공할 수 있습니다.

1. ErrorPage 컴포넌트 생성

src/pages/ErrorPage.jsx

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

function ErrorPage() {
  const error = useRouteError();
  console.error(error);

  return (
    <div style={{ padding: '2rem', textAlign: 'center' }}>
      <h1>Oops!</h1>
      <p>죄송합니다. 요청하신 페이지를 찾을 수 없습니다.</p>
      <p>
        <i>{error.statusText || error.message}</i>
      </p>
    </div>
  );
}

export default ErrorPage;

2. 라우터 설정 업데이트

src/main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import './index.css';
import App from './App';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';
import ErrorPage from './pages/ErrorPage';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />, // 공통 레이아웃 컴포넌트
    children: [
      {
        path: '/',
        element: <Home />, // 홈 페이지
      },
      {
        path: 'about',
        element: <About />, // 소개 페이지
      },
      {
        path: 'contact',
        element: <Contact />, // 연락처 페이지
      },
    ],
    errorElement: <ErrorPage />, // 에러 페이지 컴포넌트
  },
]);

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
);

3. 에러 페이지 스타일링 (선택 사항)

src/index.css

.error-page {
  padding: 2rem;
  text-align: center;
}

.error-page h1 {
  font-size: 3rem;
  margin-bottom: 1rem;
}

.error-page p {
  font-size: 1.5rem;
}

실습 요약

React Router 설정 단계

  1. React Router 설치

    npm install react-router-dom react-icons --save
  2. 라우터 설정 (src/main.jsx)

    • createBrowserRouterRouterProvider를 사용하여 라우터를 설정
    • 라우트 경로와 렌더링할 컴포넌트를 정의
  3. 레이아웃 컴포넌트 생성 (src/App.jsx)

    • 네비게이션 바와 <Outlet>을 사용하여 자식 라우트를 렌더링할 위치 지정
  4. 페이지 컴포넌트 생성 (src/pages/)

    • Home.jsx, About.jsx, Contact.jsx 등의 컴포넌트 생성
  5. 네비게이션 링크 추가 (<Link><NavLink> 컴포넌트 사용)

    • 사용자 인터페이스에서 페이지 간 이동을 가능하게 함
  6. 고급 기능 실습

    • 동적 라우팅, 네스티드 라우팅, 라우트 보호, ErrorPage 구현 등

추가 자료

React Router의 더 자세한 내용과 고급 기능에 대해서는 공식 문서를 참고하세요:


결론

React Router는 React 애플리케이션에서 클라이언트 측 라우팅을 효과적으로 관리할 수 있게 해주는 필수적인 라이브러리입니다. 이를 통해 사용자 경험을 향상시키고, 애플리케이션의 구조를 체계적으로 관리할 수 있습니다. 기본적인 라우팅 설정부터 고급 기능까지 익히면서 React 프로젝트에 적용해보세요. 꾸준한 실습과 공식 문서 참고를 통해 더욱 깊이 있는 이해를 도모할 수 있습니다.


React Router 심화 학습

React Router란?

React Router는 React 애플리케이션에서 클라이언트 측 라우팅을 관리하는 필수적인 라이브러리입니다. 이를 통해 페이지 리로드 없이 다양한 컴포넌트를 렌더링하여 사용자 경험을 향상시킬 수 있습니다.


라우팅이란?

라우팅(Routing)은 사용자가 웹 애플리케이션 내에서 특정 페이지나 뷰로 이동할 수 있도록 경로를 설정하는 과정입니다. 예를 들어, 블로그 사이트에서 "홈", "글 목록", "글 상세보기" 페이지 간의 이동을 관리합니다.


클라이언트 측 라우팅

클라이언트 측 라우팅(Client-side Routing)은 브라우저에서 자바스크립트를 사용하여 페이지 간의 전환을 관리하는 방식입니다. 전체 페이지를 다시 로드하지 않고 필요한 부분만 업데이트하여 빠르고 부드러운 사용자 경험을 제공합니다.

서버 측 라우팅과의 차이점

  • 서버 측 라우팅(Server-side Routing):
    • 사용자가 새로운 페이지를 요청할 때마다 서버가 전체 페이지를 렌더링하여 응답합니다.
    • 예: 전통적인 멀티 페이지 애플리케이션(MPA)
  • 클라이언트 측 라우팅(Client-side Routing):
    • 초기 페이지 로드 이후, 자바스크립트를 통해 필요한 부분만 업데이트하여 페이지를 전환합니다.
    • 예: 싱글 페이지 애플리케이션(SPA)

React Router 설치

React Router를 프로젝트에 설치하려면 다음 명령어를 사용하세요:

npm install react-router-dom
npm install react-icons --save

또는

yarn add react-router-dom react-icons

실습 - React Router 설정

1. 프로젝트 초기 설정

src/main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import './index.css';
import App from './App';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';
import ErrorPage from './pages/ErrorPage';
import CanvasDetail from './pages/CanvasDetail';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      { path: '/', element: <Home /> },
      { path: 'about', element: <About /> },
      { path: 'contact', element: <Contact /> },
      { path: 'canvases/:id', element: <CanvasDetail /> },
    ],
    errorElement: <ErrorPage />,
  },
]);

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
);

2. 라우팅 레이아웃 구성

src/App.jsx

import { Outlet } from 'react-router-dom';
import Header from './components/Header';

function App() {
  return (
    <>
      <Header />
      <main>
        <Outlet />
      </main>
    </>
  );
}

export default App;

3. 페이지 컴포넌트 생성

src/pages/Home.jsx

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

function Home() {
  return (
    <div>
      <h1>Home Page!</h1>
      <ul>
        <li>
          <Link to={`/canvases/1`}>1번 게시글</Link>
        </li>
        <li>
          <Link to={`/canvases/2?keyword=canvas#helloworld`}>2번 게시글</Link>
        </li>
        <li>
          <Link to={`/canvases/3`}>3번 게시글</Link>
        </li>
      </ul>
    </div>
  );
}

export default Home;

src/pages/About.jsx

function About() {
  return <div>소개 페이지입니다.</div>;
}

export default About;

src/pages/Contact.jsx

function Contact() {
  return <div>연락처 페이지입니다.</div>;
}

export default Contact;

src/pages/CanvasDetail.jsx

import { useLocation, useParams, useSearchParams } from 'react-router-dom';

function CanvasDetail() {
  const { id } = useParams(); // URL 파라미터 추출
  const [searchParams] = useSearchParams(); // 쿼리 스트링 추출
  const location = useLocation(); // 해시 및 전체 위치 정보 추출

  console.log('id:', id);
  console.log('searchParams:', searchParams.get('keyword'));
  console.log('hash:', location.hash);

  return (
    <div>
      <h1>Canvas Detail Page</h1>
      <p>ID: {id}</p>
      <p>Keyword: {searchParams.get('keyword')}</p>
      <p>Hash: {location.hash}</p>
    </div>
  );
}

export default CanvasDetail;

src/pages/ErrorPage.jsx

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

function ErrorPage() {
  const error = useRouteError();
  console.error(error);

  return (
    <div className="error-page">
      <h1>Oops!</h1>
      <p>죄송합니다. 요청하신 페이지를 찾을 수 없습니다.</p>
      <p>
        <i>{error.statusText || error.message}</i>
      </p>
    </div>
  );
}

export default ErrorPage;

1. navigate() 사용법

useNavigate 훅을 사용하면 프로그래밍 방식으로 라우트를 변경할 수 있습니다.

src/components/Header.jsx

import { useNavigate, NavLink } from 'react-router-dom';

function Header() {
  const navigate = useNavigate();
  return (
    <header className="navbar">
      <ul className="nav-links">
        {/* 프로그래밍 방식으로 라우팅 */}
        {/* 
        <li onClick={() => navigate('/')}>Home</li>
        <li onClick={() => navigate('/about')}>About</li>
        <li onClick={() => navigate('/contact')}>Contact</li> 
        */}
        
        {/* <NavLink> 컴포넌트를 사용한 라우팅 */}
        <li>
          <NavLink
            to="/"
            className={({ isActive }) => (isActive ? 'text-blue-700' : '')}
            end
          >
            Home
          </NavLink>
        </li>
        <li>
          <NavLink
            to="/about"
            className={({ isActive }) => (isActive ? 'text-blue-700' : '')}
          >
            About
          </NavLink>
        </li>
        <li>
          <NavLink
            to="/contact"
            className={({ isActive }) => (isActive ? 'text-blue-700' : '')}
          >
            Contact
          </NavLink>
        </li>
      </ul>
    </header>
  );
}

export default Header;

<NavLink>는 현재 활성화된 링크에 특정 스타일을 적용할 수 있어 사용자가 현재 어느 페이지에 있는지 시각적으로 알 수 있습니다.

사용 예시:

<NavLink
  to="/about"
  className={({ isActive }) => (isActive ? 'active-link' : '')}
>
  About
</NavLink>

CSS:

.active-link {
  color: blue;
  font-weight: bold;
}

Params, Query, Hash 실습

1. CanvasDetail 컴포넌트 생성

src/pages/CanvasDetail.jsx

import { useLocation, useParams, useSearchParams } from 'react-router-dom';

function CanvasDetail() {
  const { id } = useParams(); // URL 파라미터 추출
  const [searchParams] = useSearchParams(); // 쿼리 스트링 추출
  const location = useLocation(); // 해시 및 전체 위치 정보 추출

  console.log('id:', id);
  console.log('searchParams:', searchParams.get('keyword'));
  console.log('hash:', location.hash);

  return (
    <div>
      <h1>Canvas Detail Page</h1>
      <p>ID: {id}</p>
      <p>Keyword: {searchParams.get('keyword')}</p>
      <p>Hash: {location.hash}</p>
    </div>
  );
}

export default CanvasDetail;

2. Home 컴포넌트 수정

src/pages/Home.jsx

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

function Home() {
  return (
    <div>
      <h1>Home Page!</h1>
      <ul>
        <li>
          <Link to={`/canvases/1`}>1번 게시글</Link>
        </li>
        <li>
          <Link to={`/canvases/2?keyword=canvas#helloworld`}>2번 게시글</Link>
        </li>
        <li>
          <Link to={`/canvases/3`}>3번 게시글</Link>
        </li>
      </ul>
    </div>
  );
}

export default Home;

실습 - ErrorPage 구현

1. ErrorPage 컴포넌트 생성

src/pages/ErrorPage.jsx

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

function ErrorPage() {
  const error = useRouteError();
  console.error(error);

  return (
    <div className="error-page">
      <h1>Oops!</h1>
      <p>죄송합니다. 요청하신 페이지를 찾을 수 없습니다.</p>
      <p>
        <i>{error.statusText || error.message}</i>
      </p>
    </div>
  );
}

export default ErrorPage;

실습 요약

React Router 설정 단계

  1. React Router 설치

    npm install react-router-dom react-icons --save
  2. 라우터 설정 (src/main.jsx)

    • createBrowserRouterRouterProvider를 사용하여 라우터를 설정
    • 라우트 경로와 렌더링할 컴포넌트를 정의
  3. 레이아웃 컴포넌트 생성 (src/App.jsx)

    • Header 컴포넌트와 <Outlet>을 사용하여 자식 라우트를 렌더링할 위치 지정
  4. 페이지 컴포넌트 생성 (src/pages/)

    • Home.jsx, About.jsx, Contact.jsx, CanvasDetail.jsx, ErrorPage.jsx 등의 컴포넌트 생성
  5. 네비게이션 링크 추가 (<Link><NavLink> 컴포넌트 사용)

    • 사용자 인터페이스에서 페이지 간 이동을 가능하게 함
  6. 고급 기능 실습

    • 동적 라우팅, 네스티드 라우팅, 라우트 보호, Params, Query, Hash, ErrorPage 구현 등

추가 자료

React Router의 더 자세한 내용과 고급 기능에 대해서는 공식 문서를 참고하세요:


결론

React Router는 React 애플리케이션에서 클라이언트 측 라우팅을 효과적으로 관리할 수 있게 해주는 필수적인 라이브러리입니다. 이를 통해 사용자 경험을 향상시키고, 애플리케이션의 구조를 체계적으로 관리할 수 있습니다. 기본적인 라우팅 설정부터 고급 기능까지 익히면서 React 프로젝트에 적용해보세요. 꾸준한 실습과 공식 문서 참고를 통해 더욱 깊이 있는 이해를 도모할 수 있습니다.

profile
개발자가 되고 싶은 정치학도생의 기술 블로그

0개의 댓글