React 프로젝트를 체계적으로 관리하려면 올바른 디렉토리 구조를 갖추는 것이 중요합니다. 명확한 구조는 코드의 가독성과 유지보수성을 높여 협업을 원활하게 합니다. 이 글에서는 React 프로젝트에서 핵심적인 디렉토리와 파일을 정리하는 방법을 소개합니다.
src/main.tsx
- 애플리케이션 진입점import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
✅ 역할: React 애플리케이션을 초기화하고 루트 컴포넌트를 렌더링하는 역할을 합니다.
src/App.tsx
- 메인 컴포넌트function App() {
return (
<div className="app">
<h1>My React App</h1>
</div>
);
}
export default App;
✅ 역할: 애플리케이션의 주요 레이아웃과 라우팅을 정의합니다.
src/components/
- 재사용 가능한 UI 컴포넌트 모음components/
├── common/ # 범용 UI 컴포넌트 (버튼, 입력 필드 등)
├── layout/ # 헤더, 푸터, 사이드바 등 레이아웃 컴포넌트
├── features/ # 특정 기능과 관련된 컴포넌트
✅ 역할: UI 요소를 모듈화하여 유지보수성을 높입니다.
src/routes/
- 라우팅 관련 코드import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from '../pages/Home';
import About from '../pages/About';
function AppRoutes() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
export default AppRoutes;
✅ 역할: 애플리케이션의 화면 전환을 담당하는 구조를 정의합니다.
src/api/
- API 통신 관련 코드import axios from 'axios';
const API_URL = 'https://api.example.com';
export const fetchUsers = async () => {
const response = await axios.get(`${API_URL}/users`);
return response.data;
};
✅ 역할: 백엔드 API와의 통신을 모듈화하여 관리합니다.
src/hooks/
- 커스텀 훅 모음import { useState, useEffect } from 'react';
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(storedValue));
}, [key, storedValue]);
return [storedValue, setStoredValue] as const;
}
export default useLocalStorage;
✅ 역할: 반복적인 로직을 커스텀 훅으로 분리하여 코드 재사용성을 높입니다.
src/utils/
- 유틸리티 함수export const formatDate = (date: Date): string => {
return new Intl.DateTimeFormat('ko-KR', {
year: 'numeric', month: 'long', day: 'numeric'
}).format(date);
};
✅ 역할: 날짜 포맷팅, 문자열 변환 등 범용적인 함수를 모아둡니다.
src/types/
- TypeScript 타입 정의export interface User {
id: number;
username: string;
email: string;
role: 'admin' | 'user';
}
✅ 역할: 프로젝트에서 사용되는 공통 타입을 정의하여 일관성을 유지합니다.
src/styles/
- 스타일 관련 파일styles/
├── global.css # 전역 스타일
├── variables.scss # 색상, 폰트 등 변수
├── mixins.scss # 재사용 가능한 스타일 믹스인
✅ 역할: 스타일 관련 파일을 구조화하여 관리합니다.
src/context/
- 글로벌 상태 관리import React, { createContext, useState, useContext } from 'react';
type Theme = 'light' | 'dark';
const ThemeContext = createContext({ theme: 'light', toggleTheme: () => {} });
export const ThemeProvider: React.FC = ({ children }) => {
const [theme, setTheme] = useState<Theme>('light');
const toggleTheme = () => setTheme(theme === 'light' ? 'dark' : 'light');
return <ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>;
};
export const useTheme = () => useContext(ThemeContext);
✅ 역할: Context API를 활용해 글로벌 상태(테마, 인증 등)를 관리합니다.
디렉토리 | 설명 |
---|---|
src/assets/ | 이미지, 폰트 등 정적 파일 보관 |
src/store/ | Redux, Zustand 등 상태 관리 코드 |
src/constants/ | API URL, 상태 코드 등 상수값 |
src/services/ | 비즈니스 로직이 포함된 서비스 모듈 |
src/layouts/ | 공통 레이아웃 컴포넌트 |
src/config/ | 환경 설정 파일 (개발/프로덕션 분리) |
src/tests/ | 단위 및 통합 테스트 코드 |
src/locales/ | 다국어 번역 파일 |
React 프로젝트의 디렉토리 구조는 프로젝트의 규모와 요구사항에 따라 유동적으로 구성될 수 있습니다. 하지만 components
, routes
, api
, hooks
, utils
등의 핵심 디렉토리는 대부분의 프로젝트에서 필수적입니다. 명확한 구조를 유지하면 코드 가독성을 높이고 유지보수를 쉽게 할 수 있습니다.
이 가이드를 참고하여, 여러분의 React 프로젝트를 더 체계적으로 구성해 보세요! 🚀