1. 개요
안녕하세요! DoEatFit (v2.0) 프로젝트에 새롭게 탑승하신 동료 개발자분들을 진심으로 환영하며, 프로젝트의 빠른 온보딩을 돕는 모던 웹 개발 실무 가이드 및 기술 부채 극복기입니다.
이 문서는 신임 개발자가 로컬에서 즉시 개발 환경을 구성하고 폴더 규칙을 파악할 수 있도록 돕는 실용적인 안내서 역할을 수행해요. 이에 더해, 실제 제품을 운영하면서 자칫 방치하기 쉬운 React/Next.js 개발 시의 4대 안티패턴을 현미경처럼 집중 분석하여 성능 저하와 Hydration 에러를 원천 차단하는 기술적 극복 기록도 담고 있답니다. 본 가이드를 정독하여 우아하고 깨끗한 코드로 서비스를 함께 가꾸어나가 보아요.
2. 핵심 내용
2-1. 📂 프로젝트 온보딩을 위한 프론트/백엔드 폴더 컨벤션 및 로컬 환경 설정
DoEatFit 프로젝트는 유지보수 편의성을 높이기 위해 프론트엔드와 백엔드 모두 엄격하고 정돈된 패키지 컨벤션을 준수하고 있어요.
- Frontend 폴더 구조 (
doeatfit_front):apis/: 순수 Axios 통신 함수를 분리 정의합니다.app/: Next.js App Router 기반의 디렉토리예요. 사용자 웹 페이지인(site)와 관리자 영역인cms로 논리적으로 분리되어 있습니다.components/: UI 컴포넌트들을 보관하는 곳입니다.hooks/: 인증 인터셉터나 폼 보관 등 두터운 Custom Hook 비즈니스 로직(Facade Hook)이 머무르는 곳이에요.
- Backend 패키지 구조 (
doeatfit_back):base/: 공통 예외 처리, 통합 응답 규격(ApiResponse), 기저 엔티티(TimeStampEntity)가 모여 있습니다.domain/: 회원(user), 일지(log), 운동(workout), 식품(food) 등 핵심 도메인 비즈니스를 격리 설계하여 캡슐화 수준을 비약적으로 높였습니다.
- 쾌적한 로컬 개발 가동 팁:
- 도커 컴포즈(
docker-compose up -d) 명령어로 복잡한 인프라를 로컬에 단 1초 만에 구성할 수 있어요. - MySQL: 3306 포트로 구동됩니다 (기본 데이터베이스 스키마 생성 및 연동 확인 필수).
- MinIO: 9000(API 통신), 9001(웹 관리자 콘솔) 포트이며, 정적 이미지의 경로 접두사 정책을 준수해야 해요.
- Redis: 6379 포트로 기동되며, 인증 세션 블랙리스트 및 만료 처리를 대조 통제합니다.
- 도커 컴포즈(
2-2. 🚨 React/Next.js 개발을 흔드는 4대 치명적 안티패턴과 리팩토링 실전
최근 보안 취약점을 완벽하게 보완하며 빌드 성공을 거두었으나, 린트(Lint) 정밀 스캔 결과 성능 및 런타임 안정성을 크게 뒤흔들 수 있는 4대 아키텍처적 안티패턴이 발견되었어요. 이러한 부채를 조기에 격파할 수 있도록 원인과 명확한 리팩토링 해법을 함께 정립해 드릴게요.
❌ 안티패턴 1: Static Components (컴포넌트 내에 또 다른 컴포넌트 선언)
- 원인 및 문제점: 부모 컴포넌트 함수 블록 내부에서
const SubComponent = ...형태로 자식을 정의하면, 부모가 리렌더링될 때마다 자식 컴포넌트의 참조 주소가 아예 새롭게 재생성돼요. 이로 인해 불필요한 DOM 노드 파괴 및 재생성이 연쇄 유발되고, 무엇보다 입력 폼 컴포넌트 안에서 글자 한 자 적을 때마다 포커스가 풀려버리는 끔찍한 UX 붕괴를 초래합니다. - 해결책: 내부에 감싸져 있던 서브 컴포넌트를 메인 함수 외부(파일 하단 혹은 별도 파일)로 완전히 적출해 내고, 필요한 매개변수는 깔끔하게
props인터페이스를 통해 전달하도록 리팩토링합니다.
❌ 안티패턴 2: Effect 내에서의 조건 없는 직접적 State 업데이트
- 원인 및 문제점:
useEffect블록 내에서 방어막 없이setState를 바로 무차별 호출하면, React 렌더링이 완료된 직후 또다시 렌더링 루프를 격발하여 성능을 낭비하고 최악의 경우 무한 리렌더링 늪에 빠질 수 있습니다. - 해결책: 상태 업데이트가 꼭 필요한 찰나의 순간에만 가동되도록 명확한 **조건식(Gating)**을 씌워 실행해 주거나,
useMemo를 적극적으로 활용하여 렌더링 흐름 속에서 불필요한 갱신이 생기지 않도록 차단합니다.
❌ 안티패턴 3: 렌더링 실행 도중 불순한(Impure) 함수 호출
- 원인 및 문제점: 렌더링이 수행되는 중간 과정에
Date.now()나Math.random()처럼 매 찰나마다 결과가 변경되는 불순한(Impure) 로직을 노출하면, Next.js 서버에서 생성한 HTML 구조와 실제 브라우저가 하이드레이션(Hydration)을 거치며 매핑한 UI 결과물이 서로 불일치하는 Hydration Mismatch Error를 뱉으며 앱의 화면 안정성이 크게 깨집니다. - 해결책: 변하는 속성값을
useEffect안으로 봉인하여 브라우저에 안전히 안착한 뒤 시동되게 하거나, 최초 로딩 시 1회만 계산되도록useMemo블록 안에서 엄격히 다스려 줍니다.
❌ 안티패턴 4: 렌더링 사이클 도중 Ref 수정 시도
- 원인 및 문제점: React의 렌더링 궤도가 돌고 있는 시점에
useRef의ref.current = value값을 직접 가로채 덮어써 버리면, React가 시각적 갱신을 추적하고 데이터를 동기화하는 가상 DOM 흐름을 강제로 어지럽혀 예측할 수 없는 화면 버그를 양산하게 됩니다. - 해결책: Ref의 물리적인 값을 변경하는 로직은 반드시
useEffect콜백 안으로 감싸 배치함으로써, 브라우저가 화면을 완전하게 다 그리고 난 다음에 뒤이어 실행되도록 안전하게 조정해 줍니다.
2-3. 🛠️ 기술 부채 청산 로드맵 및 맞춤 오픈소스 라이브러리 검토
- 체계적인 3단계 부채 청산 로드맵:
- 1단계 (핵심 로직 수술): 인증 흐름을 관장하는
auth-context.tsx및 레이아웃을 제어하는use-mobile.ts내부의 불안정한 렌더링 오류를 1순위로 수정하여 서비스 전체 뼈대를 다집니다. - 2단계 (주요 폼 페이지 리팩토링): 자식 컴포넌트가 대량 내장된 회원가입(
join/page.tsx) 페이지 등 큰 폼 구성 요소들을 별도 파일로 아름답게 컴포넌트 분리 적출하여 성능 향상을 일궈냅니다. - 3단계 (경고 전면 해소): 나머지 공통 UI 컴포넌트들에 흩뿌려진 잔여 경고들을 남김없이 소거하여 결벽에 가까운 명품 코드를 달성합니다.
- 1단계 (핵심 로직 수술): 인증 흐름을 관장하는
- 추천 오픈소스 라이브러리 검토:
- React-Error-Boundary
- 평가: 예기치 않은 하위 컴포넌트의 런타임 렌더링 에러가 전체 웹 서비스 전체를 화이트스크린으로 침묵하게 만드는 것을 방지하고, 에러가 발생한 컴포넌트 영역만 “일시적인 오류가 발생했습니다”라는 세련된 Fallback UI로 정갈하게 대체 렌더링해 줍니다.
- Zustand
- 평가: Redux의 방대하고 장황한 코드를 깔끔하게 정돈하고 단 몇 줄의 순수 함수만으로 스토어를 구축해 주는 초경량 상태 통제 라이브러리로, 단순한 전역 상태 관리 및 테마 모드 등의 UI 상태 분기 장착 시 도입을 강력히 제안해요.
- Sentry
- 평가: 실시간 프로덕션 환경에서 사용자들이 겪는 JS 예외 오류와 리액트 렌더링 크래시를 즉시 포착하여 개발자 Slack 메일 등으로 Stack Trace 보고서를 즉각 전달해 주는 실시간 자가진단 모니터링 툴로 탑재를 적극 강권합니다.
- React-Error-Boundary