React 19의 use() 훅을 처음 봤을 때 반응은 대부분 같다. 문서 탭을 닫고 바로 코드베이스로 달려가 useEffect를 찾기 시작한다. 그리고 오늘 AI 코딩 도구가 있다면 그 속도는 훨씬 빠르다. "useEffect를 use()로 바꿔줘"라고 입력하는 순간, Cursor나 Claude는 3초 만에 리팩토링 코드를 내놓는다. 문제는 그 코드가 틀리지 않는다는 데 있다.
dev.to에 올라온 한 글은 이 함정을 정직하게 기록한다. 저자는 실제로 세 개의 useEffect를 use()로 고쳤고, 그 중 하나를 결국 되돌렸다. 처음 두 개는 교과서적인 성공 사례였다. 서버 컴포넌트가 fetch를 시작하고, 아직 resolve되지 않은 Promise를 클라이언트 컴포넌트에 넘기는 패턴—useState + useEffect + setUser 조합으로 18줄이었던 코드가 4줄로 줄었다. Context에서 Lazy하게 로드하는 설정 객체도 마찬가지였다. Config | null이던 타입이 Config로 좁혀지는 타입 레벨의 이득까지 챙겼다.
세 번째가 문제였다. 5초마다 상태 엔드포인트를 폴링하는 useEffect를 use()로 바꾸려 했다. 첫 번째 fetch는 잘 됐다. 그런데 재폴링이 필요했고, 언마운트 시 취소가 필요했고, jobId가 바뀔 때 재트리거가 필요했다. 20분 만에 저자는 useEffect를 더 나쁜 방식으로 재발명한 자신을 발견했다. 코드는 더 길고, 가독성은 낮고, 클린업 경로에 버그가 있었다. 결론은 단 한 줄로 정리된다. "use()는 한 번 resolve되고 취소가 필요 없는 Promise를 위한 것이다." 폴링, 웹소켓, 구독, 디바운스 검색은 여전히 useEffect의 영역이거나 SWR·TanStack Query 같은 전용 도구가 맡아야 한다.
이 이야기가 단순한 React 팁으로 끝나지 않는 이유는 마이리얼트립 허원진 CTO가 앤트로픽 글로벌 컨퍼런스 '코드 위드 클로드: 익스텐디드'에서 발표한 내용과 정확히 겹치는 지점이 있기 때문이다. 도쿄에서 열린 이 행사에서 허 CTO는 "프로토타입을 실제 서비스로 전환하는 AI 워크플로우"를 주제로 연단에 섰다. 항공권 환불 수수료 계산 같은 실무 사례를 들어 LLM 도입 시 발생하는 응답 지연, 일관성, 테스트 가능성 문제를 어떻게 극복했는지를 다뤘는데, 그가 발표에서 강조한 핵심 메시지는 이것이었다. "단순히 코드를 짜는 속도보다 '무엇을 만들지 결정하는 것'이 중요해졌다."
두 이야기는 같은 구조를 가리킨다. AI는 useEffect를 use()로 바꾸는 속도를 극적으로 높였다. 하지만 그 리팩토링이 지금 이 컴포넌트에 맞는가를 판단하는 일은 AI가 대신해줄 수 없다. use()가 빛나는 곳과 useEffect가 더 정직한 곳을 구분하는 감각은, 해당 API의 설계 의도를 이해하고 실제로 한 번 잘못 써보고 되돌린 경험에서 나온다. Cursor가 생성해준 코드가 컴파일되고 동작한다는 사실은 그 코드가 올바른 선택이라는 의미가 아니다.
이 판단력의 격차는 앞으로 더 벌어질 것이다. React Server Components, Partial Prerendering, use() 같은 신규 프리미티브들은 저마다 날카로운 사용 조건을 가지고 있다. "한 번 resolve, 취소 없음"이라는 use()의 규칙처럼, 각 도구에는 좁은 칼날이 있다. AI 코딩 도구는 그 칼날의 존재를 알려주지 않은 채 코드를 만들어낸다. 컴파일 에러가 없으면 피드백도 없다. 버그는 나중에, 더 조용한 방식으로 나타난다.
프로덕트 관점에서 보면 이는 단순한 기술 선택 문제가 아니다. 폴링 컴포넌트를 use()로 잘못 바꾼 코드가 서비스에 올라가면, 그 버그는 사용자 경험의 어느 지점에서 조용히 터진다. 상태 업데이트가 누락되거나, 언마운트 후에도 네트워크 요청이 살아있거나. 빠른 프로토타이핑이 가능해진 만큼, '이걸 쓰는 게 맞는가'를 검증하는 사이클이 개발 흐름 안에 더 명시적으로 설계되어야 한다.
실용적인 원칙은 이렇게 정리된다. 새 React 프리미티브를 배웠다면, 전체 코드베이스에 적용하기 전에 하나를 끝까지 배포해보라. git revert는 두려움의 표시가 아니라 좋은 실험의 증거다. AI가 생성한 리팩토링 코드를 받아들일 때는 "왜 이 API가 이렇게 설계됐는가"를 먼저 물어라. 그 질문에 답할 수 있는 사람이, AI가 코드의 대부분을 짜주는 시대에 나머지 판단을 맡을 수 있는 사람이다.