icon안동민 개발노트

간단한 다중 페이지 앱 만들기


 이 실습에서는 지금까지 학습한 React Router의 개념들을 활용하여 간단한 e-commerce 사이트를 구현해보겠습니다.

 이 사이트는 메인 페이지, 제품 목록 페이지, 제품 상세 페이지, 그리고 about 페이지로 구성됩니다.

1단계 : 프로젝트 설정

 먼저 새로운 React 프로젝트를 생성하고 필요한 dependencies를 설치합니다.

npx create-react-app ecommerce-app
cd ecommerce-app
npm install react-router-dom

2단계 : 기본 컴포넌트 구조 만들기

 src 폴더에 다음 컴포넌트들을 생성합니다.

  • Home.js : 메인 페이지
  • ProductList.js : 제품 목록 페이지
  • ProductDetail.js : 제품 상세 페이지
  • About.js : About 페이지
  • Navigation.js : 네비게이션 컴포넌트

3단계 : 라우팅 설정

 App.js에서 라우팅을 설정합니다.

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Navigation from './Navigation';
import Home from './Home';
import ProductList from './ProductList';
import ProductDetail from './ProductDetail';
import About from './About';
 
function App() {
  return (
    <Router>
      <div>
        <Navigation />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="products" element={<ProductList />} />
          <Route path="products/:id" element={<ProductDetail />} />
          <Route path="about" element={<About />} />
        </Routes>
      </div>
    </Router>
  );
}
 
export default App;

 이 설정은 기본적인 라우팅 구조를 제공합니다. /products/:id는 동적 라우팅을 사용하여 각 제품의 상세 페이지를 표시합니다.

4단계 : 네비게이션 구현

 Navigation.js에서 네비게이션 메뉴를 구현합니다.

import React from 'react';
import { Link } from 'react-router-dom';
 
function Navigation() {
  return (
    <nav>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/products">Products</Link></li>
        <li><Link to="/about">About</Link></li>
      </ul>
    </nav>
  );
}
 
export default Navigation;

5단계 : 제품 목록 및 상세 페이지 구현

 ProductList.js에서 제품 목록을 표시하고, 각 제품의 상세 페이지로 이동할 수 있는 링크를 제공합니다.

import React from 'react';
import { Link } from 'react-router-dom';
 
const products = [
  { id: 1, name: 'Product 1' },
  { id: 2, name: 'Product 2' },
  { id: 3, name: 'Product 3' },
];
 
function ProductList() {
  return (
    <div>
      <h1>Products</h1>
      <ul>
        {products.map(product => (
          <li key={product.id}>
            <Link to={`/products/${product.id}`}>{product.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}
 
export default ProductList;

 ProductDetail.js에서는 URL 파라미터를 사용하여 특정 제품의 정보를 표시합니다.

import React from 'react';
import { useParams } from 'react-router-dom';
 
const products = {
  1: { id: 1, name: 'Product 1', description: 'This is product 1' },
  2: { id: 2, name: 'Product 2', description: 'This is product 2' },
  3: { id: 3, name: 'Product 3', description: 'This is product 3' },
};
 
function ProductDetail() {
  let { id } = useParams();
  const product = products[id];
 
  if (!product) {
    return <div>Product not found</div>;
  }
 
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
    </div>
  );
}
 
export default ProductDetail;

6단계 : 중첩 라우팅 적용

 제품 관련 페이지들을 그룹화하기 위해 중첩 라우팅을 적용해 보겠습니다.

 App.js를 다음과 같이 수정합니다.

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Navigation from './Navigation';
import Home from './Home';
import Products from './Products';
import About from './About';
 
function App() {
  return (
    <Router>
      <div>
        <Navigation />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="products/*" element={<Products />} />
          <Route path="about" element={<About />} />
        </Routes>
      </div>
    </Router>
  );
}
 
export default App;

 그리고 새로운 Products.js 파일을 생성하여 제품 관련 라우팅을 처리합니다.

import React from 'react';
import { Routes, Route, Link, Outlet } from 'react-router-dom';
import ProductList from './ProductList';
import ProductDetail from './ProductDetail';
 
function Products() {
  return (
    <div>
      <h1>Products</h1>
      <Routes>
        <Route index element={<ProductList />} />
        <Route path=":id" element={<ProductDetail />} />
      </Routes>
      <Outlet />
    </div>
  );
}
 
export default Products;

7단계 : 404 페이지 처리

 마지막으로, 존재하지 않는 경로에 대한 처리를 추가합니다. App.js에 다음 라우트를 추가합니다.

<Route path="*" element={<NotFound />} />

 그리고 NotFound.js 컴포넌트를 생성합니다.

import React from 'react';
import { Link } from 'react-router-dom';
 
function NotFound() {
  return (
    <div>
      <h1>404 - Page Not Found</h1>
      <Link to="/">Go to Home</Link>
    </div>
  );
}
 
export default NotFound;

라우팅 결정의 이유와 장단점

  1. 기본 라우팅 구조
  • 이유 : 직관적인 URL 구조를 제공하여 사용자가 쉽게 이해하고 기억할 수 있습니다.
  • 장점 : 간단하고 명확한 구조로 유지보수가 용이합니다.
  • 단점 : 복잡한 애플리케이션에서는 더 세분화된 구조가 필요할 수 있습니다.
  1. 동적 라우팅 /products/:id
  • 이유 : 각 제품에 대해 별도의 라우트를 정의하지 않고도 모든 제품 상세 페이지를 처리할 수 있습니다.
  • 장점 : 코드의 재사용성이 높아지고, 새로운 제품을 추가할 때 라우팅 설정을 변경할 필요가 없습니다.
  • 단점 : URL 파라미터 처리에 주의가 필요하며, 잘못된 ID에 대한 예외 처리가 필요합니다.
  1. 중첩 라우팅
  • 이유 : 제품 관련 페이지들을 논리적으로 그룹화하여 구조를 개선합니다.
  • 장점 : 코드 구조가 더 체계적이 되고, 공통 레이아웃이나 로직을 쉽게 공유할 수 있습니다.
  • 단점 : 라우팅 구조가 복잡해질 수 있으며, 깊은 중첩은 가독성을 해칠 수 있습니다.
  1. 404 페이지 처리
  • 이유 : 사용자가 존재하지 않는 URL에 접근했을 때 적절한 피드백을 제공합니다.
  • 장점 : 사용자 경험이 향상되고, 애플리케이션의 완성도가 높아집니다.
  • 단점 : 추가적인 컴포넌트와 라우트 설정이 필요합니다.

 이 실습을 통해 우리는 React Router를 사용하여 기본적인 다중 페이지 애플리케이션을 구현해 보았습니다.

 이 과정에서 기본 라우팅, 동적 라우팅, 중첩 라우팅, 그리고 404 페이지 처리 등 다양한 라우팅 기술을 적용해 보았습니다.

 실제 프로젝트에서는 이보다 더 복잡한 라우팅 구조가 필요할 수 있습니다.

 예를 들어, 사용자 인증에 따른 조건부 라우팅, 더 깊은 중첩 구조, 또는 동적으로 생성되는 라우트 등을 구현해야 할 수 있습니다. 그러나 이 기본적인 구조를 이해하고 있다면, 더 복잡한 시나리오도 충분히 다룰 수 있을 것입니다.

 마지막으로, 라우팅 구조를 설계할 때는 항상 사용자 경험을 최우선으로 고려해야 합니다.

 직관적이고 일관된 URL 구조, 빠른 페이지 전환, 그리고 명확한 네비게이션은 사용자가 웹사이트를 쉽게 탐색하고 이용할 수 있게 해줍니다. 또한, SEO를 고려한 URL 구조 설계도 중요한 요소입니다.

 이러한 원칙들을 염두에 두고 라우팅을 구현한다면, 사용자 친화적이고 유지보수가 용이한 React 애플리케이션을 개발할 수 있을 것입니다.