마법의 라이브 코딩

432025년 09월 27일3

“그래서 우리는 질문했습니다. 이 문제들을 해결할, 더 나은 방법은 없을까?”

댄의 목소리에 미세한 변화가 감지되었다. 문제 제기에서 해결책 제시로 넘어가는, 발표의 클라이맥스를 향한 전주곡이었다. 그는 슬라이드를 코드 에디터 화면으로 전환했다.

“여기, 친구의 이름과 온라인 상태를 보여주는 간단한 클래스 컴포넌트가 있습니다.”

스크린에는 constructor, componentDidMount, componentDidUpdate, componentWillUnmount 등 온갖 생명주기 메서드로 가득 찬, 전형적인 클래스 컴포넌트 코드가 나타났다. 청중에게는 너무나도 익숙한 모습이었다.

“이제, 이 코드를 함께 리팩토링해 보겠습니다.”

댄의 손가락이 키보드 위에서 춤을 추기 시작했다.
그는 망설임 없이 class FriendStatus extends React.Component 라는 선언문을 통째로 지워버렸다. 객석에서 나지막한 탄성이 터져 나왔다. 리액트의 심장과도 같은 클래스를 지워버린 것이다.

대신, 그는 평범한 자바스크립트 함수를 선언했다.
function FriendStatus(props) { ... }

constructor도, super(props)도, this.state도 모두 사라졌다.
그 빈자리에, 댄은 청중이 처음 보는 함수를 타이핑했다.

const [isOnline, setIsOnline] = useState(null);

“이것이 useState입니다. 컴포넌트에 상태를 추가하는 새로운 방법이죠.”

이어서 그는 componentDidMountcomponentWillUnmount에 흩어져 있던 구독 관련 로직을 모두 지웠다. 그리고 그 자리에 또 다른 낯선 함수를 호출했다.

useEffect(() => {
  ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
  return () => {
    ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
  };
});

“이것은 useEffect입니다. 부수 효과를 다루는 새로운 방법이죠.”

장내에는 미묘한 정적이 흘렀다. 사람들은 방금 무슨 일이 일어났는지 이해하려 애쓰고 있었다.
댄은 키보드에서 손을 떼고, 청중을 향해 돌아섰다.

“보시다시피, 이제 친구 상태를 구독하고 해지하는, 서로 관련 있는 코드가 완벽하게 하나의 블록 안에 함께 있습니다. 우리는 더 이상 생명주기 메서드 사이를 오갈 필요가 없습니다.”

그의 말이 끝나자, 객석의 분위기가 술렁이기 시작했다.
복잡하고 장황했던 클래스 코드가, 불과 십여 줄의 간결하고 읽기 쉬운 함수로 바뀌는 마법이 눈앞에서 펼쳐진 것이다. this도, bind도, 복잡한 생명주기 메서드도 없었다.

개발자들은 자신들이 겪어온 고통이 단 몇 분 만에 사라지는 것을 목격했다.
“세상에…”
“저게 어떻게 가능한 거지?”

하지만 이것은 아직 시작에 불과했다.
댄이 준비한 진짜 마법은, 아직 공개되지 않았다. 그는 이제 로직 재사용이라는, 개발자들의 가장 오래된 숙원을 해결할 비장의 무기를 꺼내 보일 참이었다. 그 순간, 청중의 놀라움은 경악으로 바뀔 터였다.