컴포넌트가 화면에 나타난 직후, 무언가 하고 싶다

682025년 10월 22일3

생명주기(Lifecycle)라는 거대한 개념이 제시되자, 팀은 가장 시급하고 중요한 문제부터 해결하기로 했다. 바로 "컴포넌트가 화면에 나타난 직후, 무언가 하고 싶다"는 개발자들의 근본적인 요구사항이었다.

이 요구는 다양한 시나리오에서 발생했다.

  • <NewsNotifier>처럼, 화면에 나타난 순간부터 주기적인 작업을 시작해야 할 때.
  • <UserProfile>처럼, 일단 기본적인 틀을 먼저 보여준 뒤, 상세 프로필 정보를 서버에 비동기적으로 요청해야 할 때.
  • <Modal>처럼, 화면에 나타난 직후 특정 입력 필드에 자동으로 포커스를 맞춰주고 싶을 때.
  • jQuery 플러그인 같은 외부 라이브러리를 특정 DOM 요소에 적용해야 할 때.

이 모든 작업은 공통점을 가지고 있었다.
첫째, 이것들은 부작용(Side Effects)이다. render 메서드의 순수성을 해치는, 외부 세계와의 상호작용이다.
둘째, 이 작업들은 반드시 실제 DOM이 생성된 이후에 실행되어야 한다. DOM이 없는데 포커스를 맞출 수도, jQuery 플러그인을 붙일 수도 없기 때문이다.

조던 워크는 이 명확한 요구사항을 해결하기 위해, 생명주기 목록에서 가장 중요한 메서드 중 하나를 꺼내 들었다.

componentDidMount()

이 이름은 그 역할을 명확하게 설명하고 있었다.

  • component: 이 메서드는 컴포넌트 인스턴스에 속한다.
  • Did: 과거형 시제. 어떤 일이 ‘일어난 후’를 의미한다.
  • Mount: ‘마운트하다’, 즉 컴포넌트가 생성한 버추얼 DOM이 실제 DOM에 성공적으로 삽입되어 화면에 나타나는 과정을 의미한다.

종합하면, componentDidMount는 "컴포넌트가 실제 DOM에 마운트된 직후, 리액트가 호출해주는 약속된 갈고리(Hook)"였다.

맷은 이 새로운 메서드를 사용하여 자신의 <NewsNotifier> 컴포넌트를 수정했다.

var NewsNotifier = React.createClass({
  getInitialState: function () {
    return { hasNewNotification: false };
  },

  // 컴포넌트가 실제 DOM에 성공적으로 렌더링된 '직후'에 호출된다.
  componentDidMount: function () {
    console.log('NewsNotifier가 방금 화면에 나타났습니다!');

    // 이제 이곳에서 안전하게 타이머를 시작할 수 있다.
    // this.timerID는 나중에 타이머를 정리하기 위해 인스턴스에 저장한다.
    this.timerID = setInterval(this.checkForNotifications, 5000);
  },

  checkForNotifications: function () {
    // ... 서버에 새로운 소식이 있는지 확인하는 로직 ...
    // 만약 새 소식이 있다면, this.setState({ hasNewNotification: true }) 호출
  },

  render: function () {
    // ... 이전과 동일한 render 코드 ...
  },
});

코드는 아름답게 분리되었다.

  • render는 오직 현재 상태를 보고 무엇을 그릴지만 순수하게 정의한다.
  • componentDidMount는 컴포넌트의 렌더링 결과가 실제 DOM에 반영된 것을 확인한 후, 타이머를 설정하는 ‘부작용’을 책임진다.

이제 render가 몇 번 호출되든 상관없었다. componentDidMount는 컴포넌트의 생애 동안 단 한 번, 성공적으로 화면에 나타난 그 결정적인 순간에만 실행될 것이기 때문이다.

이 메서드의 도입은 리액트의 세계와 외부 세계(브라우저 API, 서버, 다른 라이브러리)를 잇는 공식적인 첫 번째 다리가 되었다. 개발자들은 더 이상 부작용을 일으키는 코드를 어디에 둬야 할지 고민하며 편법을 쓰지 않아도 되었다.

리액트는 componentDidMount라는 안전하고 예측 가능한 공간을 제공함으로써, 개발자들이 안심하고 외부 세계와 소통할 수 있는 길을 열어주었다. 이것은 리액트가 단순한 렌더링 엔진을 넘어, 완전한 애플리케이션을 구축할 수 있는 견고한 프레임워크로 진화하는 중요한 한 걸음이었다.