React 쇼핑몰 index.js·App.js 분석: 프로젝트 구조와 라우팅 흐름 완벽 정리
React

React 쇼핑몰 index.js·App.js 분석: 프로젝트 구조와 라우팅 흐름 완벽 정리


쇼핑몰 코드를 처음 보면 복잡해 보이죠? 상품 목록, 상세 페이지, 장바구니, 게시판까지… 이 코드들이 어떻게 연결되어 있는지 파악하기 어려울 수 있어요.

이 시리즈에서는 이미 완성된 과일 쇼핑몰 예제코드를 함께 분석하면서 React 쇼핑몰의 전체 구조를 이해해볼 거예요. 오늘 1편에서는 프로젝트의 기본 구조를 파악하고, 앱이 어떻게 시작되는지 알아봅니다.

이번 편에서 알아볼 내용

  • ✅ 쇼핑몰 예제코드에서 사용하는 기술 스택
  • ✅ React 앱의 전체 폴더 구조
  • ✅ index.js - React 앱의 시작점
  • ✅ Provider와 BrowserRouter의 역할
  • ✅ App.js - 메인 컴포넌트 구조

이 쇼핑몰에서 사용하는 기술 스택

분석할 쇼핑몰에서는 다음 기술들을 사용해요:

graph LR
    A["React 19"] --> B["React Router v6"]
    A --> C["Redux Toolkit"]
    A --> D["Bootstrap 5"]
    A --> E["Axios"]
    
    style A fill:#61DAFB,color:#000
    style B fill:#CA4245,color:#fff
    style C fill:#764ABC,color:#fff
    style D fill:#7952B3,color:#fff
    style E fill:#5A29E4,color:#fff
기술용도
React 19UI 컴포넌트 개발
React Router v6페이지 간 이동
Redux Toolkit전역 상태 관리 (장바구니)
Bootstrap 5빠른 UI 스타일링
Axios외부 데이터 요청

프로젝트 생성하기

이 프로젝트를 직접 만들어보려면 다음 순서로 진행하세요:

# 1. 프로젝트 생성
npx create-react-app shop

# 2. 폴더 이동
cd shop

# 3. 필요한 라이브러리 설치
npm install react-router-dom @reduxjs/toolkit react-redux bootstrap react-bootstrap axios

# 4. 개발 서버 실행
npm start

프로젝트 폴더 구조

쇼핑몰 프로젝트를 열면 이런 구조가 보여요:

shop/
├── public/
│   ├── img/              # 상품 이미지들
│   │   ├── fruit1.jpg ~ fruit9.jpg
│   │   └── veggie/
│   │       └── veggie1.jpg ~ veggie3.jpg
│   └── index.html
├── src/
│   ├── components/       # 화면을 구성하는 컴포넌트들
│   │   ├── Products.js      # 상품 카드
│   │   ├── Detail.js        # 상품 상세
│   │   ├── Cart.js          # 장바구니
│   │   ├── BoardList.js     # 게시판 목록
│   │   └── ...
│   ├── db/               # 상품 데이터
│   │   ├── fruit.js         # 과일 데이터
│   │   └── veggie.js        # 채소 데이터
│   ├── App.js            # ⭐ 메인 컴포넌트
│   ├── store.js          # ⭐ Redux 상태 저장소
│   └── index.js          # ⭐ 앱 시작점
└── package.json

⭐ 표시된 파일이 가장 중요한 핵심 파일들이에요!

앱의 시작 흐름 이해하기

React 앱이 브라우저에서 어떻게 실행되는지 순서대로 살펴볼게요:

graph TD
    A["index.html<br/>(빈 HTML 파일)"] --> B["index.js<br/>(React 진입점)"]
    B --> C["Provider 감싸기<br/>(Redux 연결)"]
    C --> D["BrowserRouter 감싸기<br/>(라우팅 활성화)"]
    D --> E["App.js<br/>(실제 화면 렌더링)"]
    
    style A fill:#e1f5ff
    style B fill:#ffe1e1
    style C fill:#e1d5ff
    style D fill:#fff4e1
    style E fill:#e1ffe1

하나씩 자세히 볼게요!

index.js - 앱의 시작점

src/index.js 파일은 이렇게 생겼어요:

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

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

코드를 하나씩 뜯어볼게요:

1. Import 부분

import {BrowserRouter} from 'react-router-dom';  // 라우팅
import { Provider } from 'react-redux';          // Redux 연결
import store from './store';                     // 우리가 만든 store

2. Provider - Redux 연결하기

<Provider store={store}>
  ...
</Provider>

Provider는 Redux 상태를 앱 전체에서 사용할 수 있게 해줘요. 마치 전기 콘센트에 플러그를 꽂는 것처럼, 앱에 Redux를 “꽂아주는” 역할이에요.

store는 장바구니 같은 전역 데이터를 저장하는 곳이에요. 4편에서 자세히 알아볼 거예요!

3. BrowserRouter - 라우팅 활성화

<BrowserRouter>
  <App />
</BrowserRouter>

BrowserRouter로 감싸야 URL에 따라 다른 페이지를 보여줄 수 있어요:

  • / → 홈 (상품 목록)
  • /detail/1 → 1번 상품 상세
  • /cart → 장바구니
  • /board → 게시판

왜 이렇게 감싸는 걸까?

graph TB
    subgraph "감싸는 순서 (바깥 → 안쪽)"
        P["Provider<br/>(Redux 상태 전달)"]
        B["BrowserRouter<br/>(URL 라우팅)"]
        A["App<br/>(실제 화면)"]
        P --> B --> A
    end
    
    style P fill:#e1d5ff
    style B fill:#fff4e1
    style A fill:#e1ffe1

비유로 설명하면:

  • Provider = 전기 콘센트 (상태라는 전기를 공급)
  • BrowserRouter = 건물 복도 (어느 방으로 갈지 안내)
  • App = 실제 방 (화면에 보이는 내용)

App.js - 메인 컴포넌트 구조

이제 src/App.js를 볼게요. 이 파일이 쇼핑몰의 실제 화면을 담당해요.

전체 구조 미리보기

graph TD
    subgraph App["App.js"]
        N["Navbar<br/>(상단 메뉴)"]
        R["Routes<br/>(페이지 라우팅)"]
    end
    
    R --> Home["/ (홈)<br/>상품 목록"]
    R --> Detail["/detail/:id<br/>상품 상세"]
    R --> Cart["/cart<br/>장바구니"]
    R --> About["/about<br/>회사소개"]
    R --> Board["/board<br/>게시판"]
    
    style App fill:#f8f9fa
    style N fill:#343a40,color:#fff
    style Home fill:#e1ffe1
    style Detail fill:#e1f5ff
    style Cart fill:#ffe1e1
    style About fill:#fff4e1
    style Board fill:#e1d5ff

Import 부분

import { useState } from "react";
import "./App.css";
import { Navbar, Container, Nav, Button } from "react-bootstrap";
import data from "./db/fruit";
import Products from "./components/Products";
import { Routes, Route, useNavigate } from "react-router-dom";
import Detail from "./components/Detail";
import Cart from "./components/Cart";
// ... 더 많은 import

여기서 중요한 것들:

  • useState - 상태를 관리하는 React Hook
  • react-bootstrap - 이쁜 UI 컴포넌트들
  • data from "./db/fruit" - 과일 상품 데이터
  • Routes, Route, useNavigate - 페이지 이동 도구

상태(State) 정의

App.js에서 관리하는 상태들을 살펴볼게요:

function App() {
  // 과일 상품 데이터
  const [fruit, setFruit] = useState(data);
  
  // 채소 상품 데이터
  let [veggie, setVeggie] = useState(data2);
  
  // 더 보기 버튼 클릭 횟수
  let [count, setCount] = useState(1);
  
  // 검색어 입력값
  let [input, setInput] = useState("");
  
  // 게시판 글 목록
  const [posts, setPosts] = useState([
    {
      id: 1,
      title: "사과는 언제 배송이 되나요?",
      content: "어제부터 기다렸는데 아직 배송이 안됐어요.",
      author: "김과일",
      date: new Date().getTime(),
      views: 1,
    },
    // ...
  ]);
  
  const navigate = useNavigate();
  // ...
}
<Navbar bg="dark" variant="dark">
  <Container>
    <Navbar.Brand onClick={() => navigate("/")}>
      과일농장
    </Navbar.Brand>
    <Nav className="me-auto">
      <Nav.Link onClick={() => navigate("/")}>홈으로</Nav.Link>
      <Nav.Link onClick={() => navigate("/detail/1")}>상세페이지</Nav.Link>
      <Nav.Link onClick={() => navigate("/cart")}>장바구니</Nav.Link>
      <Nav.Link onClick={() => navigate("/about")}>회사소개</Nav.Link>
      <Nav.Link onClick={() => navigate("/board")}>게시판</Nav.Link>
    </Nav>
  </Container>
</Navbar>

useNavigate를 사용하면 클릭했을 때 다른 페이지로 이동할 수 있어요.

Routes - 페이지 라우팅

<Routes>
  {/* 홈 페이지 */}
  <Route path="/" element={<div>... 상품 목록 ...</div>} />
  
  {/* 상품 상세 */}
  <Route path="/detail/:paramId" element={<Detail fruit={fruit} veggie={veggie} />} />
  
  {/* 장바구니 */}
  <Route path="/cart" element={<Cart />} />
  
  {/* 회사소개 (중첩 라우팅) */}
  <Route path="/about" element={<About />}>
    <Route path="member" element={<Member />} />
    <Route path="location" element={<Location />} />
  </Route>
  
  {/* 게시판 */}
  <Route path="/board" element={<BoardList posts={posts} ... />} />
  <Route path="/board/write" element={<BoardWrite onAdd={handleAddPost} />} />
  <Route path="/board/:id" element={<BoardDetail posts={posts} ... />} />
  <Route path="/board/edit/:id" element={<BoardEdit posts={posts} ... />} />
  
  {/* 404 페이지 */}
  <Route path="/*" element={<NotFound />} />
</Routes>

여기서 핵심 포인트:

  • path="/" - URL이 /이면 이 컴포넌트를 보여줘
  • :paramId - 동적 파라미터 (1, 2, 3 등 어떤 값이든 받음)
  • element={<컴포넌트 />} - 해당 URL에서 보여줄 컴포넌트

정리

오늘 1편에서 살펴본 내용을 정리하면:

graph LR
    A["index.js"] --> B["Provider<br/>(Redux 연결)"]
    B --> C["BrowserRouter<br/>(라우팅)"]
    C --> D["App.js<br/>(Navbar + Routes)"]
    
    style A fill:#ffe1e1
    style B fill:#e1d5ff
    style C fill:#fff4e1
    style D fill:#e1ffe1

핵심 포인트:

  1. 📦 index.js는 앱의 시작점이고, Provider와 BrowserRouter로 App을 감싼다
  2. 🔌 Provider는 Redux 상태를 앱 전체에 공급한다
  3. 🛣️ BrowserRouter는 URL에 따라 다른 화면을 보여준다
  4. 📱 App.js는 Navbar(상단메뉴)와 Routes(페이지들)로 구성된다

다음 편에서는 상품 목록이 화면에 어떻게 표시되는지, 검색과 정렬은 어떻게 동작하는지 알아볼게요!


시리즈 전체 보기


댓글 남기기

궁금한 점이나 나누고 싶은 이야기가 있다면 자유롭게 남겨주세요.
여러분의 소중한 의견이 블로그를 성장시킵니다! 🌱

💡 오늘의 명언

"꽃은 자신을 누구와 비교하지 않는다. 그저 피어날 뿐이다."

✍️ 작성하기

💬0개의 댓글

댓글을 불러오는 중입니다...