- 클래스 컴포넌트와 생명주기 메서드
- JSX를 쓰기 위한 불필요한 React 임포트
- 이제는 필요 없어진 ref 전달 방식
- 오래된 라우팅 라이브러리 문법
이 파트에서 다루는 내용
React는 변화가 빨라서 낡은 코드가 섞여 나옵니다
React는 10년 넘게 작성 방식이 여러 번 바뀌었습니다. 클래스 컴포넌트에서 함수 컴포넌트로, 그리고 훅 이후에도 권장 패턴이 계속 정리돼 왔습니다.
AI가 학습한 자료에는 이 모든 시기가 섞여 있습니다. 그래서 요청하면 동작은 하지만 지금은 권장되지 않는 형태의 코드가 나오는 일이 잦습니다.
게다가 React는 잘못 써도 화면이 일단 그려집니다. 문제가 드러나는 시점이 데이터가 늘어난 뒤라서 발견이 늦습니다.
- 이펙트로 값을 계산해 상태에 저장
- 목록 key에 배열 인덱스 사용
- 서버 데이터를 전역 상태에 저장
- 필요 없는 곳에 붙은 메모이제이션
- 이미 있는 공용 컴포넌트를 다시 만듦
- 팀이 쓰지 않는 라이브러리를 전제로 작성
- 프로젝트 폴더 구조와 다른 위치에 파일 생성
AI가 만든 React 코드를 볼 때 첫 질문은 '동작하는가'가 아닙니다. 화면은 대개 잘 그려집니다. 물어야 할 것은 '지금 권장되는 방식인가'와 '데이터가 늘어나도 괜찮은가'입니다.
버전과 규칙을 파일로 못 박습니다
대화로 매번 알려 주는 것은 관리가 아닙니다. 프로젝트 규칙을 파일로 저장소에 두면 팀 전체가 같은 기준으로 AI를 씁니다. IDE 코스와 Spring Boot 코스에서 다룬 방식과 같습니다.
# 프로젝트 규칙
## 환경
- React 19, TypeScript, Vite
- 서버 데이터는 TanStack Query, 전역 상태는 Zustand
- 클래스 컴포넌트를 만들지 않는다. 함수 컴포넌트와 훅만 사용한다
## 코드 규칙
- props와 상태에 타입을 명시한다. any 를 쓰지 않는다
- 목록 key 에 배열 인덱스를 쓰지 않는다
- 계산 가능한 값을 별도 상태로 만들지 않는다
- 서버 데이터는 전역 상태에 저장하지 않는다
- 폴더는 features/<기능> 구조를 따른다
## 이펙트 규칙
- useEffect 는 외부 시스템 동기화에만 사용한다
- 값 계산, 이벤트 처리, 상태 연쇄 변경에 사용하지 않는다
- 구독과 타이머에는 반드시 클린업을 작성한다
## 금지 사항
- 환경변수에 비밀키를 넣지 않는다
- 요청 범위 밖 파일을 수정하지 않는다
- 기존 공용 컴포넌트를 두고 새로 만들지 않는다
## 검증
- 변경 후 npm run build 로 확인한다
- 변경 파일과 이유를 요약해 보고한다금지 사항을 구체적으로 적는 것이 효과적입니다. '좋은 코드를 작성하라'는 지시는 결과를 바꾸지 못하지만 '목록 key 에 배열 인덱스를 쓰지 않는다'는 그대로 지켜집니다.
AI 코드에서 반드시 확인할 지점
앞의 13개 파트에서 다룬 함정 중 AI 생성 코드에서 특히 자주 나타나는 항목을 모았습니다. 이 순서로 훑으면 대부분 걸립니다.
생명주기 메서드가 보이면 함수 컴포넌트로 바꿉니다. 오래된 학습 자료에서 그대로 나옵니다.
배열 인덱스나 무작위 값이 key로 쓰였는지 확인합니다. 데이터가 정적일 때는 문제가 안 보입니다.
다른 상태로 계산할 수 있는 값을 별도 상태로 만들지 않았는지 봅니다. 두 값이 어긋나는 버그의 원인입니다.
배열이나 객체를 직접 수정하고 다시 설정하는 코드가 있는지 확인합니다. 화면이 갱신되지 않습니다.
폼 제출에 처리 중 상태와 버튼 비활성이 있는지 봅니다. AI가 자주 빠뜨립니다.
값 계산이나 부모 알림을 이펙트로 처리했는지 확인합니다. 가장 흔하게 나오는 문제입니다.
의존성이 빠졌거나 린트 경고를 무시한 흔적, 구독·타이머의 클린업 누락을 확인합니다.
측정 없이 useMemo와 useCallback이 붙어 있으면 걷어냅니다. 코드만 복잡해집니다.
서버에서 받은 목록을 전역 상태에 저장했는지 확인합니다. 갱신 로직을 직접 만들게 됩니다.
성공 경로만 구현된 경우가 많습니다. 세 가지 상태가 모두 처리됐는지 봅니다.
API 키가 프런트엔드 환경변수나 코드에 들어갔는지 확인합니다. 빌드 결과물에 그대로 노출됩니다.
타입 오류를 any로 덮은 부분이 있는지 봅니다. 검사만 꺼지고 문제는 남습니다.
내부 상태나 클래스 이름을 검증하는 테스트는 리팩터링을 막습니다. 사용자 관점으로 바꿉니다.
이미 있는 공용 컴포넌트나 훅을 다시 만들지 않았는지 확인합니다. AI는 기존 코드를 모두 알지 못합니다.
맡기기 좋은 작업과 그렇지 않은 작업
- 반복되는 목록·폼·테이블 화면 초안
- 타입 정의와 변환 코드 작성
- 테스트 코드 초안 (검증 항목은 사람이 정함)
- 낯선 컴포넌트 코드 설명
- 오류 메시지와 빌드 실패 원인 해석
- 접근성 속성 보완 제안
- 상태를 어디에 둘지 결정
- 컴포넌트 분리 경계 설계
- 성능 문제의 원인 진단
- 라이브러리 도입 여부 판단
- 사용자 흐름과 화면 설계
구조와 상태 위치는 사람이 정하고 구현을 맡기는 방식이 안정적입니다. 화면 하나를 통째로 맡기면 검토 비용이 작성 비용보다 커집니다.
책임은 코드를 병합한 사람에게 있습니다
AI가 작성했다는 사실은 품질에 대한 면책이 되지 않습니다. 화면이 느려지거나 데이터가 어긋났을 때 원인을 찾고 고치는 것은 사람입니다.
그래서 이해하지 못한 코드는 병합하지 않는다는 기준이 가장 중요합니다. 설명할 수 없는 코드는 문제가 생겼을 때도 손댈 수 없습니다.
- AI로 생성·수정한 범위를 PR에 남깁니다.
- 화면을 실제로 열어 동작을 확인한 뒤 병합합니다.
- 추가된 의존성은 필요성과 번들 크기 영향을 따로 확인합니다.
- 사내 코드의 외부 전송 가능 여부를 먼저 확인합니다. 도구별 차이는 IDE 코스에서 다룹니다.
- 프롬프트에 접속 정보와 개인정보를 넣지 않습니다.
이 코스에서 다룬 문제는 대부분 '화면은 잘 뜨는데 나중에 문제가 되는 것'들이었습니다. AI는 화면이 뜨는 코드를 빠르게 만들어 주지만, 나중에 문제가 될지는 판단하지 못합니다. 그 판단을 하기 위해 앞의 13개 파트가 필요했습니다.
버전별 참고
본문은 React 19 기준입니다. 18과 달라지는 부분은 아래에 정리합니다.
- 규칙 파일에 React 버전과 사용 중인 라이브러리를 반드시 적습니다. 적지 않으면 클래스 컴포넌트나 구버전 라우팅 문법이 섞여 나옵니다.
- React 19를 쓴다면 ref 전달 방식과 폼 관련 훅 기준을 규칙에 명시해 두면 재작업이 줄어듭니다.
- 생성된 코드에 같은 구버전 패턴이 반복해서 나타나면 규칙 파일에 금지 항목으로 추가합니다. 대화로 매번 교정하는 것보다 효과적입니다.