2026.02.10Claude Code 활용
claude-code팀에이전트리팩토링병렬작업React워크플로우

Claude Code 팀 에이전트로 대규모 React 컴포넌트 리팩토링 병렬 처리하기

문제: 거대해진 사이드바 컴포넌트

OpenClaude 프로젝트를 개발하면서 사이드바 레이아웃이 단일 파일에 모든 로직이 집중된 상태가 되었습니다. 프로젝트 목록, 세션 관리, 채팅 영역, 상태 관리가 하나의 컴포넌트에 뒤섞여 있어 유지보수가 어려워졌고, 이를 체계적으로 분리하는 리팩토링이 필요했습니다.

리팩토링 범위가 넓어 단계별로 나누되, Claude Code의 팀 에이전트(Team Agent) 기능을 활용해 Phase별 병렬 작업을 시도했습니다.

5 Phase 리팩토링 설계

전체 작업을 의존 관계에 따라 5단계로 분리했습니다.

Phase 1: 커스텀 훅 분리 (useProjects, useSessions) Phase 2: Context 설계 (ChatContext) Phase 3: 사이드바 컴포넌트 분리 (SidebarProjectList, SidebarHeader 등) Phase 4: ChatArea + 페이지 재작성 Phase 5: 스타일 정리 + 미사용 코드 제거

핵심은 Phase 13과 Phase 45를 두 개의 Worker 에이전트에 각각 할당하여 병렬로 처리한 것입니다. Phase 13은 기반 레이어(훅, Context, 사이드바 UI)를 담당하고, Phase 45는 이를 소비하는 상위 레이어(채팅 영역, 페이지 통합)를 담당합니다.

팀 에이전트 구성

Claude Code의 팀 기능은 team-lead가 작업을 분배하고, worker 에이전트들이 각자의 Phase를 수행하는 구조입니다.

code
team-lead (조율자)
├── worker-phase123: Phase 1~3 담당
└── worker-phase45:  Phase 4~5 담당

team-lead는 각 Worker에게 작업 지시를 내리면서 필요한 컨텍스트를 함께 전달합니다. 예를 들어 worker-phase45에게는 Phase 1~3에서 이미 생성된 파일 목록과 각 파일의 export 인터페이스를 명시해주어, Worker가 존재하지 않는 파일을 import하는 실수를 방지했습니다.

팀 에이전트 워크플로우

Phase별 작업 내용

Phase 1: 커스텀 훅 분리

사이드바에 인라인으로 들어있던 데이터 페칭 로직을 독립 훅으로 추출했습니다.

typescript
// ~/src/hooks/useProjects.ts
export function useProjects() {
  const [projects, setProjects] = useState<Project[]>([]);
  // API 호출, 로딩/에러 상태 관리
  return { projects, isLoading, error, refetch };
}

// ~/src/hooks/useSessions.ts
export function useSessions(projectName: string) {
  const [sessions, setSessions] = useState<Session[]>([]);
  // 프로젝트별 세션 목록 관리
  return { sessions, isLoading, createSession, deleteSession };
}

`formatRelativeTime()` 같은 유틸리티 함수도 이 단계에서 훅 파일로 함께 분리했습니다.

Phase 2: Context 설계

사이드바와 채팅 영역이 공유하는 상태를 ChatContext로 통합했습니다.

typescript
// ~/src/contexts/ChatContext.tsx
interface ChatContextType {
  currentProject: string | null;
  currentSession: string | null;
  selectSession: (project: string, session: string) => void;
  messages: Message[];
  sendMessage: (content: string) => void;
}

export const ChatProvider: React.FC = ({ children }) => {
  // 프로젝트/세션 선택 상태 + 메시지 상태 통합 관리
};

export const useChatContext = () => useContext(ChatContext);

기존에 props drilling으로 전달하던 상태들이 Context 하나로 정리되면서, 컴포넌트 간 의존성이 크게 줄었습니다.

Phase 3: 사이드바 컴포넌트 분리

하나의 거대한 사이드바를 역할별로 분리했습니다.

Sidebar/

code
├── SidebarHeader.tsx      — 로고, 새 채팅 버튼
├── SidebarProjectList.tsx — 아코디언 프로젝트/세션 목록
└── SidebarFooter.tsx      — 설정, 사용자 정보

Phase 4~5: ChatArea 재작성 + 정리

worker-phase45는 Phase 1~3에서 만든 훅과 Context를 import하여 ChatArea를 재작성하고, 기존의 레거시 컴포넌트를 삭제한 뒤 빌드 검증까지 수행했습니다.

typescript
// ChatArea에서 Context 활용
const ChatArea = () => {
  const { messages, sendMessage, currentSession } = useChatContext();
  // 깔끔한 구조로 재작성
};

병렬 작업의 실제 흐름

Worker 에이전트의 실제 작업 흐름은 다음과 같았습니다.

  1. team-lead가 두 Worker를 동시에 생성
  2. worker-phase123: 훅 생성 → Context 생성 → 사이드바 컴포넌트 분리
  3. worker-phase45: 기존 파일 분석 → Phase 1~3 결과물 확인 → ChatArea 재작성
  4. worker-phase45: 레거시 파일 삭제 → 빌드 실행 → PM2 재시작
  5. 각 Worker가 team-lead에게 완료 보고

Phase 45 Worker는 Phase 13의 결과물에 의존하지만, team-lead가 생성될 파일의 인터페이스를 미리 전달했기 때문에 실제로는 거의 동시에 작업을 시작할 수 있었습니다. 다만 Phase 45 Worker가 실제 import를 할 때는 Phase 13의 파일이 이미 디스크에 존재해야 하므로, 파일 생성 순서에 대한 조율은 team-lead가 담당했습니다.

코드 리팩토링

핵심 정리

팀 에이전트를 활용한 리팩토링에서 배운 점:

  • 작업 분할 기준은 의존 관계: Phase를 나눌 때 가장 중요한 것은 각 Phase 간의 의존성을 명확히 파악하는 것입니다. 독립적인 Phase는 병렬화하고, 의존 관계가 있는 Phase는 순서를 보장해야 합니다.

  • 인터페이스를 먼저 확정: 병렬 Worker가 서로의 결과물을 사용해야 할 때, export할 함수/타입의 시그니처를 먼저 합의하면 실제 구현이 끝나기 전에 소비하는 쪽의 작업을 시작할 수 있습니다.

  • team-lead의 역할이 핵심: Worker에게 충분한 컨텍스트(기존 파일 구조, 이미 생성된 파일 목록, 타입 정의)를 전달하는 것이 성공의 열쇠입니다. 컨텍스트가 부족하면 Worker가 잘못된 가정 위에 코드를 작성하게 됩니다.

  • 빌드 검증은 마지막 Worker에 포함: 모든 Phase가 끝난 뒤 빌드를 실행하여 통합 검증을 하면, 분리된 작업이 실제로 잘 조합되는지 확인할 수 있습니다.

팀 에이전트 기능은 단순 코드 생성을 넘어, 리팩토링처럼 여러 파일을 동시에 수정해야 하는 대규모 작업에서 진가를 발휘합니다. 특히 "Phase를 나누고, 인터페이스를 합의하고, 병렬 실행 후 통합 검증"이라는 패턴은 다른 대규모 리팩토링에도 그대로 적용할 수 있는 워크플로우입니다.