지금까지 배운 내용을 종합한 미니 프로젝트 구현
이 최종 프로젝트에서는 "Task Manager" 애플리케이션을 구현하며 지금까지 학습한 React 개념과 기술을 종합적으로 적용해볼 것입니다.
이 애플리케이션은 사용자가 작업을 생성, 조회, 수정, 삭제할 수 있는 기능을 제공합니다.
프로젝트 요구사항
- 사용자 인증 (로그인/로그아웃)
- 작업 목록 표시
- 새 작업 추가
- 작업 수정 및 삭제
- 작업 필터링 및 정렬
- 반응형 디자인
1단계 : 프로젝트 설정
Create React App을 사용하여 프로젝트를 생성합니다.
npx create-react-app task-manager
cd task-manager
npm install react-router-dom axios styled-components
2단계 : 컴포넌트 구조 설계
src/
components/
Auth/
Login.js
Signup.js
Tasks/
TaskList.js
TaskItem.js
TaskForm.js
Layout/
Header.js
Footer.js
pages/
Home.js
Dashboard.js
context/
AuthContext.js
TaskContext.js
api/
auth.js
tasks.js
hooks/
useAuth.js
useTasks.js
App.js
3단계 : 라우팅 구현
App.js에서 라우팅을 설정합니다.
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './pages/Home';
import Dashboard from './pages/Dashboard';
import Login from './components/Auth/Login';
import Signup from './components/Auth/Signup';
import { AuthProvider } from './context/AuthContext';
function App() {
return (
<AuthProvider>
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/dashboard" component={Dashboard} />
<Route path="/login" component={Login} />
<Route path="/signup" component={Signup} />
</Switch>
</Router>
</AuthProvider>
);
}
export default App;
4단계 : 상태 관리 전략
Context API를 사용하여 전역 상태를 관리합니다.
import React, { createContext, useState, useContext } from 'react';
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const login = (userData) => {
setUser(userData);
};
const logout = () => {
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
5단계 : API 통합
axios를 사용하여 API 요청을 처리합니다.
import axios from 'axios';
const API_URL = 'https://api.example.com';
export const getTasks = async () => {
const response = await axios.get(`${API_URL}/tasks`);
return response.data;
};
export const createTask = async (taskData) => {
const response = await axios.post(`${API_URL}/tasks`, taskData);
return response.data;
};
// 추가 API 요청 함수들...
6단계 : 컴포넌트 구현
import React, { useState, useEffect } from 'react';
import { getTasks } from '../../api/tasks';
import TaskItem from './TaskItem';
function TaskList() {
const [tasks, setTasks] = useState([]);
useEffect(() => {
const fetchTasks = async () => {
const tasksData = await getTasks();
setTasks(tasksData);
};
fetchTasks();
}, []);
return (
<div>
{tasks.map(task => (
<TaskItem key={task.id} task={task} />
))}
</div>
);
}
export default TaskList;
7단계 : 폼 처리 및 유효성 검사
TaskForm.js에서 React Hook Form을 사용하여 폼 처리와 유효성 검사를 구현합니다.
import React from 'react';
import { useForm } from 'react-hook-form';
import { createTask } from '../../api/tasks';
function TaskForm() {
const { register, handleSubmit, errors } = useForm();
const onSubmit = async (data) => {
try {
await createTask(data);
// 성공 처리
} catch (error) {
// 에러 처리
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
name="title"
ref={register({ required: 'Title is required' })}
placeholder="Task title"
/>
{errors.title && <span>{errors.title.message}</span>}
<textarea
name="description"
ref={register}
placeholder="Task description"
/>
<button type="submit">Add Task</button>
</form>
);
}
export default TaskForm;
8단계 : 성능 최적화
- React.memo를 사용하여 불필요한 리렌더링 방지
- useCallback과 useMemo를 활용하여 함수와 값 메모이제이션
- 리스트 렌더링 최적화를 위해 가상화 기법 적용
9단계 : 스타일링
styled-components를 사용하여 컴포넌트 스타일링을 적용합니다.
import styled from 'styled-components';
const TaskItemWrapper = styled.div`
background-color: #f0f0f0;
border-radius: 4px;
padding: 16px;
margin-bottom: 8px;
`;
function TaskItem({ task }) {
return (
<TaskItemWrapper>
<h3>{task.title}</h3>
<p>{task.description}</p>
</TaskItemWrapper>
);
}
10단계 : 테스팅
Jest와 React Testing Library를 사용하여 컴포넌트 테스트 작성하기
import React from 'react';
import { render, screen } from '@testing-library/react';
import TaskItem from './TaskItem';
test('renders task title', () => {
const task = { id: 1, title: 'Test Task', description: 'Test Description' };
render(<TaskItem task={task} />);
const titleElement = screen.getByText(/Test Task/i);
expect(titleElement).toBeInTheDocument();
});
11단계 : 배포
Netlify를 사용하여 애플리케이션 배포
- Netlify 계정 생성
- GitHub 저장소와 연동
- 빌드 설정 :
npm run build
- 배포 트리거 : main 브랜치에 push
프로젝트 확장 제안
- 작업 우선순위 설정 기능 추가
- 작업 완료 날짜 추적 및 알림 기능
- 팀 협업 기능 (작업 할당, 공유 등)
- 드래그 앤 드롭으로 작업 순서 변경
- 데이터 시각화 (작업 진행 상황 차트 등)
개발 과정 회고
이 프로젝트를 통해 React의 핵심 개념들을 실제로 적용해보았습니다. 컴포넌트 구조 설계, 상태 관리, 라우팅, API 통합 등 각 단계에서 배운 내용을 종합적으로 활용할 수 있었습니다. 특히 Context API를 사용한 전역 상태 관리와 커스텀 훅을 통한 로직 재사용은 코드의 구조화와 재사용성 향상에 큰 도움이 되었습니다.
성능 최적화 과정에서는 React의 렌더링 최적화 기법들을 적용해보며, 대규모 애플리케이션에서의 성능 관리의 중요성을 체감할 수 있었습니다. 또한, 테스팅 과정을 통해 안정적인 애플리케이션 개발의 기초를 다질 수 있었습니다.
추가 개선 방향
- 서버 사이드 렌더링 도입 : Next.js를 활용하여 초기 로딩 성능 개선
- 상태 관리 라이브러리 도입 : Redux나 MobX를 사용하여 더 복잡한 상태 관리 시나리오 대응
- 마이크로 프론트엔드 아키텍처 적용 : 대규모 확장을 위한 구조 개선
- 접근성 개선 : ARIA 속성 추가 및 키보드 네비게이션 지원
- 국제화(i18n) 지원 : 다국어 지원을 위한 구조 도입
이 프로젝트는 React 개발의 기초부터 고급 기술까지 다양한 측면을 경험할 수 있는 좋은 시작점입니다.
앞으로 React 생태계의 다양한 도구와 라이브러리를 탐험하며, 더 복잡하고 규모 있는 애플리케이션을 개발할 수 있는 기반을 마련했습니다.
지속적인 학습을 통해 더 나은 React 개발자로 성장할 수 있기를 바랍니다.