Claude Code로 Flutter UI를 반복하는 실무 루프: 사용자 스토리를 위젯 트리, 상태, 네비게이션으로 바꾸되 변경을 모듈식으로 유지하고 리뷰하기 쉽게 만드는 방법.

text\nlib/\n features/\n orders/\n screens/\n widgets/\n state/\n routes.dart\n\n\n위젯을 작고 조합 가능하게 유지하세요. 위젯이 명확한 입력과 출력을 가지면 상태 로직을 건드리지 않고도 레이아웃을 바꿀 수 있고, UI를 다시 쓰지 않고 상태를 바꿀 수 있습니다. 전역 상태 대신 평범한 값과 콜백을 받는 위젯을 선호하세요.\n\n리뷰 가능하게 유지하는 루프 예시:\n\n- 슬라이스에 대한 3~6줄 UI 스펙 작성(무엇이 나타나고, 탭이 무엇을 하는지, 로딩/에러/빈 상태가 어떻게 보이는지).\n- 필요한 최소 파일만 생성하거나 편집(대개 한 화면과 한두 위젯).\n- 화면을 실행하고, 한 번의 정리 패스(네이밍, 간격, 사용되지 않는 props 제거).\n- 슬라이스에 맞는 커밋 메시지로 커밋.\n\n엄격한 규칙을 세우세요: 모든 변경은 되돌리기 쉽거나 격리 가능해야 합니다. 반복 중에는 끼어들기식 리팩터를 피하세요. 관련 없는 문제를 발견하면 적어두고 별도 커밋에서 고치세요.\n\n툴이 스냅샷과 롤백을 지원하면 각 슬라이스를 스냅샷 포인트로 사용하세요. Koder.ai 같은 일부 비브 코딩 플랫폼은 스냅샷과 롤백을 포함해 실험을 더 안전하게 만듭니다.\n\n초기 반복을 얌전하게 유지하는 또 하나의 습관: 공유 위젯을 편집하기보다 새 위젯을 추가하는 것을 선호하세요. 공유 컴포넌트는 작은 변경이 큰 Diff로 번지는 곳입니다.\n\n## 단계별: 사용자 스토리에서 위젯 트리 생성하기\n\n빠른 UI 작업은 사고와 타자를 분리할 때 안전합니다. 먼저 코드 생성 전에 명확한 위젯 트리 계획을 세우세요.\n\n1) 위젯 트리 개요만 요청하세요. 위젯 이름, 계층, 각 부분이 무엇을 보여주는지 원합니다. 아직 코드는 필요 없습니다. 이렇게 하면 상태 누락, 빈 화면, 이상한 레이아웃 선택 같은 것을 싸게 잡을 수 있습니다.\n\n2) 책임별 컴포넌트 분해를 요청하세요. 각 위젯을 집중시키세요: 하나는 헤더, 하나는 리스트, 하나는 빈/에러 UI를 렌더링합니다. 나중에 상태가 필요하면 지금 메모만 하고 아직 구현하지 마세요.\n\n3) 화면 스캐폴드와 stateless 위젯을 생성하세요. 플레이스홀더 컨텐츠와 명확한 TODO가 있는 단일 스크린 파일로 시작하세요. 입력은 명시적으로 유지(생성자 파라미터)하여 나중에 실제 상태를 쉽게 연결할 수 있게 합니다.\n\n4) 스타일과 레이아웃 세부사항은 별도 패스로 처리하세요: 간격, 타이포그래피, 테마, 반응형 동작. 스타일링을 별도의 Diff로 분리하면 리뷰가 단순해집니다.\n\n### 효과적인 프롬프트 패턴\n\n제약을 앞에 두어 어시스턴트가 실무에 맞지 않는 UI를 만들지 않게 하세요:\n\n- 목표 기기(폰만, 태블릿 포함, 방향)\n- 디자인 제약(Material 3, 기존 테마 색상, 간격 규칙)\n- 네비게이션 기대(뒤로 동작, 딥 링크 여부)\n- 수락 기준(무엇이 보여지고 탭 가능해야 하는가)\n- 기존 코드 경계(어떤 파일/위젯은 그대로 있어야 하는지, 네이밍 규칙)\n구체적 예시: 사용자 스토리가 "사용자는 저장된 항목을 검토하고 하나를 제거할 수 있다"라면 앱바, 항목 행이 있는 리스트, 빈 상태를 포함하는 위젯 트리를 요청하세요. 그런 다음 SavedItemsScreen, SavedItemTile, EmptySavedItems 같은 분해를 요청하세요. 그 다음에 stateless 위젯과 가짜 데이터를 가진 스캐폴드를 생성하고 마지막에 스타일(구분선, 패딩, 명확한 제거 버튼)을 추가하세요.
작고 테스트 가능한 UI 스펙을 먼저 만드세요. 3–6줄로 아래를 커버합니다:
그런 다음 그 슬라이스(대개 한 화면 + 1–2개의 위젯)만 만드세요.
스토리를 네 가지 버킷으로 정리하세요:
수락 기준을 빠르게 설명할 수 없다면 스토리는 아직 UI로 바꾸기엔 불명확합니다.
먼저 위젯 트리 개요(이름 + 계층 + 각 부분이 무엇을 보여주는지)만 생성하도록 요청하세요. 코드 금지.
그다음 컴포넌트 책임 분해(각 위젯의 역할)를 요청하세요.
그다음에야 입력(값 + 콜백)을 명확히 한 상태로 stateless scaffold를 생성하고, 스타일링은 별도의 패스로 진행하세요.
원칙: 한 의도당 한 번의 반복.\n\n- 반복 A: 위젯 트리/레이아웃\n- 반복 B: 상태 연결\n- 반복 C: 네비게이션 연결\n\n하나의 커밋에 레이아웃, 상태, 라우트를 모두 바꾸면 리뷰어가 무엇 때문에 문제가 생겼는지 알기 어렵고 롤백이 복잡해집니다.
위젯은 덤하게 유지하세요: 상태를 렌더링만 하고 비즈니스 규칙을 결정하지 않게 합니다.
실용적 기본값:
build() 안에 비동기 호출을 넣지 마세요—재빌드 시 반복 호출로 이어집니다.
코딩 전에 상태와 전이를 평범한 문장으로 적어 두세요.
일반 패턴 예시:
그다음 어떤 이벤트가 상태를 바꾸는지(새로고침, 재시도, 제출, 편집)를 나열하세요. 코드가 문서와 비교하기 쉬워집니다.
스토리별로 작은 “흐름 지도”를 만드세요:\n\n- 진입: 사용자가 어디서 오는가\n- 다음: 주요 전진 경로\n- 취소: 중단하면 어디로 가는가\n- 뒤로: 뒤로가 무엇을 보존/버리는가\n- 대체경로: 필요한 데이터가 없으면 어떻게 처리할지
화면 간 전달되는 파라미터(ID, 필터, 임시 데이터)를 고정하세요. 그렇지 않으면 글로벌 싱글턴에 문맥을 숨기게 됩니다.
기본은 기능별 폴더 구조로 변경 범위를 한정하는 것입니다. 예시:
lib/features/<feature>/screens/lib/features/<feature>/widgets/lib/features/<feature>/state/lib/features/<feature>/routes.dart각 반복은 한 기능 폴더 내에서만 작업하고 주변 코드를 건드리지 마세요.
인터페이스(입력/출력)를 안정화하고 내부는 자유롭게 바꾸세요.
리뷰어는 입력/출력이 안정적인지에 더 관심이 많습니다.
2분 점검 리스트:
가능하면(스냅샷/롤백 지원 시) 큰 레이아웃 변경 전 스냅샷을 찍어두세요.