본문 바로가기

최종 프로젝트

자율 프로젝트의 한 사용자 흐름을 정하고, 정상·실패 상태와 README·배포·회고 기록으로 완료 여부를 판단합니다.

이 절에서는 만들고 싶은 앱의 사용자 흐름 하나를 골라, 어디까지 만들면 첫 버전을 마쳤다고 할지 정합니다. 화면을 구현한 뒤에는 정상·실패 상태와 시작 방법을 남겨 다른 사람도 결과를 확인할 수 있게 합니다.


최종 프로젝트의 목표

이 최종 프로젝트는 강제로 특정 기능을 요구하지 않습니다.

주제와 기능은 스스로 정하되, 첫 버전에는 선택한 흐름에 필요한 도구만 사용합니다. 여러 페이지, 외부 API, 별도 상태 관리 라이브러리는 앱이 필요로 할 때 추가해도 됩니다.

핵심 목표

아이디어 구상 및 기획: 여러분이 만들고 싶은 앱의 주제와 주요 기능을 스스로 정의합니다.

프로젝트 초기화: Vite(권장) 또는 여러분이 선호하는 다른 방식으로 프로젝트를 시작합니다.

컴포넌트 설계 및 구현: 앱의 구조를 컴포넌트 단위로 나누어 설계하고, 각 컴포넌트를 구현합니다.

  • 현재 화면에 필요한 state부터 정하고, 외부 연결이나 상태 공유가 필요할 때 해당 훅을 선택합니다. 배운 훅을 모두 사용하는 것이 목표는 아닙니다.

상태 관리: 앱의 복잡도에 따라 useState, useReducer, Context API 중 적절한 상태 관리 기법을 선택하여 적용합니다. (선택적으로 Redux, Zustand 등 외부 라이브러리 사용도 가능)

라우팅 구현: 여러 화면의 주소가 필요하다면 react-router-dom으로 페이지 이동을 구현합니다. 한 화면 안에서 끝나는 앱에는 필수 조건이 아닙니다.

데이터 페칭 및 관리: 외부 데이터가 필요한 앱이라면 fetch나 Axios 등으로 요청하고 로딩·빈 결과·오류를 함께 표시합니다. 로컬 데이터만 사용하는 앱은 그 데이터의 변경과 저장 흐름을 확인합니다.

성능 확인과 필요한 최적화: 느린 동작이 있다면 React Developer Tools의 Profiler 등으로 비용을 먼저 확인합니다. React.memo, useCallback, useMemo는 확인한 원인에 맞을 때 적용하고 변경 전후를 비교합니다.

배포: 앱을 공개하려면 빌드 결과와 실제 호스트의 동작을 확인합니다. 아래 dist 정적 배포 안내는 Vite SPA 기준입니다. 서버 기능을 포함한 다른 프레임워크는 해당 배포 방식을 사용합니다.

호스팅 서비스에 맞는 SPA rewrite를 설정합니다. _redirects는 Netlify 방식이며 다른 호스트에 그대로 적용되는 공통 규격은 아닙니다.

(선택) Git & CI/CD: GitHub/GitLab 저장소를 만들고, Netlify/Vercel의 자동 배포 기능을 활용하여 CI/CD 워크플로우를 경험합니다.


프로젝트 아이디어 제안

너무 거창할 필요는 없습니다.

작지만 여러분이 흥미를 느끼는 주제를 선택하는 것이 중요합니다.

다음은 몇 가지 아이디어 제안입니다.

  • To-Do List (고급 버전)
    • 상태 관리 심화 (Context API 또는 useReducer)
    • 필터링, 정렬 기능 (useMemo 활용)
    • 아이템 편집, 삭제 기능
    • 라우팅 (예: todos/active, todos/completed)
    • 로컬 스토리지에 데이터 저장/불러오기
  • 간단한 날씨 앱
    • 외부 날씨 API (OpenWeatherMap 등) 연동
    • 도시 검색 및 선택 기능
    • 현재 날씨 및 예보 표시
    • React Query로 데이터 페칭 최적화
  • 영화/도서 검색 앱
    • 영화/도서 정보 API (TMDB, Naver 책 API 등) 연동
    • 검색 기능 및 결과 목록 표시
    • 상세 정보 페이지 (라우팅)
    • 로딩 스피너, 에러 메시지 처리
  • 간단한 포트폴리오 웹사이트
    • 자기소개, 스킬, 프로젝트 목록 페이지
    • 반응형 디자인 (미디어 쿼리 또는 Styled Components)
    • 연락처 폼 (Netlify Forms 활용)
  • 미니 쇼핑몰 상품 목록
    • 가상의 상품 데이터 표시
    • 카테고리별 필터링, 가격 정렬
    • 상품 상세 페이지
    • 장바구니 기능 (상태 관리 중요)
  • 간단한 그림판/메모장
    • canvas 엘리먼트를 이용한 그리기 기능
    • 텍스트 입력, 저장/불러오기
    • 상태 관리가 중요

팁: 너무 복잡한 아이디어보다는, 핵심 기능을 먼저 구현하고 점진적으로 확장하는 것을 추천합니다.

아이디어를 고른 뒤에는 첫 버전에 남길 기능과 다음 버전으로 미룰 기능을 나누어야 완성 가능성이 높아집니다.


프로젝트 진행 가이드

진행 가이드는 체크리스트처럼 훑기보다, 실행 가능한 마일스톤 단위로 끊어 관리하면 좋습니다.

주제 선정 및 기능 정의
  • 무엇을 만들고 싶은가요?
  • 첫 버전에서 사용자가 끝낼 흐름 하나는 무엇인가요? 정상 결과와 실패했을 때의 안내를 먼저 적습니다.
  • 어떤 데이터가 필요한가요? (정적 데이터, 외부 API?)
  • 그 흐름에 어떤 화면과 주소가 필요한가요? 여러 주소가 필요할 때 라우팅 경로를 정합니다.
프로젝트 시작
npm create vite@latest my-final-project -- --template react --no-interactive
cd my-final-project
npm install

또는 선호하는 Next.js 등으로 시작해도 좋습니다. 이후 명령과 dist 정적 배포 설명은 Vite SPA 기준이며, 다른 프레임워크의 서버 기능에는 별도 배포 방식이 필요합니다.

환경 설정
  • 라우팅이 필요하면 react-router-dom을 설치합니다: npm install react-router-dom
  • 외부 API를 사용할 경우, axios 또는 fetch 준비
  • 공통 스타일은 src/index.css, 컴포넌트에 연결한 스타일은 해당 CSS 파일에 둡니다. 파일 연결이 낯설다면 첫 React 앱의 App.css 편집을 복습합니다.
컴포넌트 구조 설계
  • src/components/, src/pages/, src/hooks/, src/utils/ 등으로 폴더를 나누어 코드의 응집도를 높입니다.
  • 각 컴포넌트의 역할과 프롭스, 상태를 간략하게 스케치합니다.
핵심 기능 구현 (반복)
  • 가장 중요한 기능부터 차례로 구현합니다.
  • 각 기능을 구현할 때마다 useState, useEffect 등 적절한 훅을 사용합니다.
  • UI와 로직을 분리하는 연습을 합니다.
  • React Developer Tools로 컴포넌트 트리와 상태 변화를 확인합니다.
라우팅 적용
  • 여러 주소가 필요하다면 src/App.jsx 또는 src/main.jsx에서 BrowserRouter가 앱을 감싸도록 설정합니다.
  • Routes와 Route 컴포넌트를 사용하여 페이지 라우팅을 구현합니다.
  • Link 컴포넌트나 useNavigate 훅으로 페이지 이동을 구현합니다.
데이터 페칭 및 관리
  • useEffect를 사용하여 컴포넌트 마운트 시 데이터를 가져옵니다.
  • 로딩 상태, 에러 상태를 처리하여 사용자에게 피드백을 줍니다.
  • 서버 데이터의 캐시·갱신 규칙이 복잡해지면 React Query나 SWR 도입을 따로 검토합니다. 첫 흐름을 완료하려고 새 라이브러리를 반드시 추가할 필요는 없습니다.
성능 최적화 적용
  • 성능 문제가 있는 동작에서 Profiler로 렌더링 비용을 확인합니다. 아래 기법은 비용의 원인에 맞는 것만 선택합니다.
  • React.memo로 렌더링 비용이 높은 컴포넌트를 감쌉니다.
  • useCallback으로 자식 컴포넌트에 전달되는 콜백 함수를 메모이제이션합니다.
  • useMemo로 고비용 계산 결과나 참조가 중요한 객체/배열을 메모이제이션합니다.
  • 적용 후 다시 프로파일링하여 개선 효과를 확인합니다. 과도한 최적화는 피합니다.
배포 준비
  • 프로젝트 코드를 GitHub/GitLab 등 원격 저장소에 푸시합니다.
  • Netlify에서는 public/_redirects의 /* /index.html 200으로 기본 SPA rewrite를 구성할 수 있습니다. 이 광범위한 규칙은 누락 자산도 HTML 200으로 가릴 수 있으므로 운영 경로 정책에 맞춰 범위를 정합니다. 다른 호스트는 해당 서비스 설정을 사용합니다.
배포
  • npm run build 명령어를 실행하여 빌드합니다.
  • Netlify, Vercel 등 선호하는 정적 호스팅 서비스에 접속하여 Git 저장소와 연동하고 dist 폴더를 배포합니다.
  • 배포된 URL에서 첫 버전의 핵심 흐름과 실패 상태를 확인합니다. 여러 경로를 쓰면 해당 주소를 직접 열었을 때도 동작하는지 확인합니다. 배포하지 않았다면 로컬에서 확인한 결과와 배포 미확인을 나누어 기록합니다.

목록 조회 하나를 끝내는 예

첫 버전의 범위를 게시물 목록 읽기와 조회 실패 시 재시도로 정했다고 해 보겠습니다. 아래는 완료 기록을 남기는 예이며, 자신의 프로젝트를 반드시 게시판으로 바꿀 필요는 없습니다.

이미 Axios 게시판을 만들었다면 조회 컴포넌트와 페이지 연결·실패 확인을 이어서 봅니다. 다른 앱이라면 그 앱의 한 흐름에 같은 질문을 적용합니다.

작은 단계독자가 확인할 끝점남길 기록
첫 범위 정하기목록 읽기와 조회 재시도까지 만든다. 새 글 작성·삭제는 이번 범위에 넣지 않는다.README의 목표, 필요한 데이터, 다음 버전으로 미룬 기능
화면과 상태 잇기/posts에서 로딩 뒤 목록을 보여 준다. 빈 배열은 빈 목록 안내, 조회 실패는 오류와 다시 시도 버튼으로 구분한다.route·컴포넌트·state·API 주소, 사용한 데이터와 기대 결과
실패 후 복구하기API를 사용할 수 없을 때 오류 안내가 나오고, API를 복구한 뒤 다시 시도하면 GET 조회 결과가 목록으로 바뀐다.기대와 실제 화면, 실패 확인 위치, 다시 시도한 결과
다른 사람이 시작할 수 있게 하기프로젝트 폴더와 명령, 데이터 준비, 접속 주소를 추측하지 않고 같은 흐름을 시작할 수 있다.README의 사용한 버전·설치/실행 명령·API와 seed 준비·확인한 것과 미확인한 것
배포와 회고 남기기배포했다면 실제 URL에서 같은 흐름을 확인한다. 아직 배포하지 않았다면 미확인으로 남긴다.실제 URL 또는 미확인 상태, 관찰한 결과, 다음 개선 하나

조회가 실패하면 브라우저 Network의 GET /posts 주소와 응답을 먼저 봅니다. 이어서 mockApi.js의 baseURL, useAxios의 오류 처리, PostList의 error·onRetry 연결을 확인합니다. 조회 재시도는 GET을 다시 보내는 행동입니다. 이미 성공한 글 추가나 삭제를 다시 실행하는 것과 구분합니다.

Vite 클라이언트를 호스팅했다고 4000번 포트에서 실행한 로컬 json-server까지 배포되는 것은 아닙니다. 외부 API가 필요한 앱은 실제 접속 가능한 API 주소와 호스트의 환경 설정·CORS 조건을 따로 준비합니다. README에는 로컬 목록을 확인한 사실과 배포 환경의 API 연결을 확인한 사실을 나누어 적습니다.

다음 기능은 이 기록을 바탕으로 고릅니다. 처음부터 기능 수를 늘리기보다 한 흐름의 정상 결과, 실패 복구, 시작 방법을 설명할 수 있는지 먼저 확인합니다.

아래는 한 사용자 흐름을 검증·배포·회고로 이어가는 진행 방식입니다. 같은 digest의 승격과 rollback 기록은 직접 구성할 릴리스 절차이며, 앞의 Git 연동 설정만으로 완료된 것으로 간주하지 않습니다.

범위 정의 → 한 사용자 흐름 구현 → 상태·접근성·테스트·빌드 검증 → 릴리스 → 실제 결과 관찰 → 회고 → 다음 범위. 각 단계에서 수용 기준과 완료 증거를 갱신한다.

PROJECT SCOPE / DELIVERY LOOP

한 사용자 흐름을 구현·검증·회고로 이어간다

작은 범위의 사용자 흐름을 route·UI·상태·데이터까지 연결한다. 기능 검증과 빌드·배포 뒤 실제 결과를 기록하고, 회고에서 확인한 사실을 다음 범위에 반영한다.

한 사용자 흐름을 구현·검증·회고로 이어간다범위 정의 → 한 사용자 흐름 구현 → 상태·접근성·테스트·빌드 검증 → 릴리스 → 실제 결과 관찰 → 회고 → 다음 범위. 각 단계에서 수용 기준과 완료 증거를 갱신한다.1. 범위 정의사용자 결과 · 비목표2. 한 흐름 구현route · UI · 상태 · 데이터3. 검증 + 빌드상태 · 접근성 · 테스트4. 릴리스검증한 산출물 전달5. 실제 결과 관찰핵심 행동 · 오류6. 회고 후 반복다음 작은 범위
한 사용자 흐름의 전달·관찰·회고 순환범위→한 흐름 구현→검증과 빌드→릴리스→실제 결과 관찰→회고의 여섯 노드와 다섯 순방향 간선, 회고에서 범위로 되돌아가는 한 간선을 유지한다. 왼쪽 돌아가는 화살표는 기록한 사실로 다음 범위를 정한다는 뜻이다. 기능 수나 특정 도구를 강제하지 않는다.1. 범위 정의사용자 결과 · 비목표2. 한 흐름 구현route · UI · 상태 · 데이터3. 검증 + 빌드상태 · 접근성 · 테스트4. 릴리스검증한 산출물 전달5. 실제 결과 관찰핵심 행동 · 오류6. 회고 후 반복다음 작은 범위

01 / SCOPE

사용자 결과와 첫 버전 범위를 정한다

핵심 기능·데이터·페이지 경로와 이번에 다루지 않을 기능을 기록한다. 기능 수를 늘리기보다 한 흐름의 성공·실패 조건을 먼저 정한다.

02 / IMPLEMENT

한 사용자 흐름을 끝까지 연결한다

route, UI, 상태 소유 위치와 데이터 경계를 함께 구현한다. 작은 컴포넌트와 필요한 Hook을 사용하고, 새 도구는 앱의 요구에 맞춰 선택한다.

03 / VERIFY

예외 상태와 빌드까지 확인한다

loading·empty·error·success, 키보드·접근성, 핵심 흐름 테스트를 확인한다. 성능은 측정 후 변경한다. production build와 실제 자산·깊은 URL 동작을 검증한다.

04 / RELEASE

호스트에 맞는 릴리스 절차를 구성한다

Vite SPA의 dist를 전달하고 호스트의 rewrite·캐시 정책을 설정한다. 검증한 동일 파일의 digest 승격과 rollback 대상 기록은 별도로 구성할 절차이며 Git 연동만으로 완료되지 않는다.

05 / OBSERVE

실제 URL에서 기대와 결과를 비교한다

핵심 행동·오류·배포 결과를 기록한다. README, 재현 방법, 검증 기록, release ID와 복구 대상을 공유 기록에 남긴다.

06 / RETROSPECT

사실을 다음 범위의 근거로 삼는다

틀린 가정·부족한 증거·다음 개선점을 정하고 첫 단계로 돌아간다. 모든 단계에서 수용 기준과 완료 증거를 갱신한다.

다음 개선은 기록한 결과를 기준으로 고른다. 이 장의 dist 정적 배포는 Vite SPA 기준이며 다른 프레임워크의 서버 기능에는 별도 배포 방식이 필요하다.


다른 사람이 시작할 수 있는지 확인하기

README의 명령을 쓴 뒤에는 자신의 기억을 제외하고 그 문장만 따라갈 수 있는지 확인합니다. 작업 폴더, 사용한 버전, 실행할 명령, 필요한 데이터·API와 시작 주소를 나눠 적습니다. API가 없는 로컬 프로젝트에는 API 설치 단계를 억지로 추가하지 않습니다. 로컬 값이 새로고침 뒤 유지되는지 여부도 선택한 저장 방식의 관찰 결과로 남깁니다.

예시

로컬 데이터로 할 일 추가·완료·삭제 흐름을 정했다면 '빈 목록 → Mina의 할 일 추가 → 완료 표시 → 삭제 → 빈 목록 안내'를 첫 범위로 둘 수 있습니다. 저장하지 않는 state 예제라면 새로고침 뒤 초기 목록으로 돌아오는 것이 조건입니다. 저장 기능을 추가했다면 저장 성공·실패와 복원 동작을 별도 범위로 확인합니다. 외부 API나 라우팅을 사용하지 않았다는 사실 자체는 미완성의 근거가 아닙니다.

완료 범위와 다음 개선을 독립적으로 판단하기

게시물 GET 목록 조회·실패 안내·재시도는 로컬에서 확인했습니다. README에는 프런트 실행 명령만 있고 필요한 API의 시작·seed 안내가 없습니다. 배포 URL에서는 API 연결이 실패했습니다. 새 글 POST가 실패한 뒤 GET 재조회는 성공했습니다. 첫 버전 전체를 “배포 완료, 글 작성까지 성공”이라고 기록할 수 있나요? 원래 범위인 목록 조회를 유지하면서 다음 개선 한 가지를 고른다면 무엇을 먼저 재현하나요?

관찰한 흐름별로 기록하는 풀이

로컬 목록 조회·복구는 확인한 범위입니다. README만으로 다른 사람이 API를 시작할 수 없으므로 데이터 준비와 실행 안내를 보완하고 그대로 따라갈 수 있는지 확인합니다. 배포 환경의 API 실패는 미해결로 남깁니다. 배포 URL을 만들었다는 사실과 그 URL에서 목록 흐름을 마쳤다는 사실을 나눕니다.

GET 재조회 성공은 목록을 읽었다는 증거이며 앞선 POST의 저장 성공을 증명하지 않습니다. 선택한 첫 범위가 목록 조회라면 작성 기능을 이번 완료 조건에 몰래 추가하거나 그 성공을 주장하지 않습니다. 다음 개선은 배포 환경의 실패한 GET 주소·응답·환경 값과 API 접근 조건을 재현해 원인을 찾는 것으로 잡을 수 있습니다. 자신의 프로젝트가 API 없이 끝나는 로컬 흐름이라면 그 흐름의 입력·실패·시작 방법을 기준으로 판단합니다.

셀프 피드백 및 개선

프로젝트를 완성한 후, 다음 질문들을 스스로에게 던져보며 피드백하고 개선점을 찾아보세요.

  • 이 앱에서 가장 중요한 기능은 무엇이었나요? 잘 구현되었나요?
  • 코드는 이해하기 쉽고 유지보수하기 쉬운가요?
  • 컴포넌트들은 각자의 책임에 따라 잘 분리되어 있나요?
  • 상태 관리는 효율적이었나요?
  • 성능 문제는 없었나요? 최적화는 적절히 이루어졌나요?
  • 다음 버전에서는 어떤 기능을 추가하고 싶은가요?
  • 이 프로젝트를 통해 새로 배운 점은 무엇인가요?
  • 어려웠던 점은 무엇이었고, 어떻게 해결했나요?

마무리: React 학습 이후 확인할 것

이 책에서는 React의 핵심 개념, 컴포넌트 기반 개발, 상태 관리, 훅, 라우팅, 데이터 페칭, 성능 최적화, 배포 흐름을 다뤘습니다.

최종 프로젝트에서 한 흐름을 구현했다면 남긴 기록을 살펴보세요. 정상·실패 상태와 시작 방법을 설명할 수 있는지, 배포한 경우 실제 URL에서도 같은 결과를 확인했는지에 따라 현재 완료 범위를 정할 수 있습니다.

웹 개발 생태계는 빠르게 바뀌지만, React의 핵심 개념을 이해하면 새 도구를 평가하고 적용하는 기준을 세우기 쉽습니다.

이후에는 공식 문서와 실제 프로젝트를 기준으로 부족한 주제를 하나씩 보완하는 방식으로 학습을 이어가면 됩니다.