render() 메서드, 무엇을 그릴지 알려주다

482025년 10월 02일4

React.createClass를 이용한 첫 번째 컴포넌트가 성공적으로 동작하자, 팀의 관심은 자연스럽게 그 심장부, render 메서드의 역할과 책임에 집중되었다. 톰은 render의 중요성을 다시 한번 강조했다.

“이 render 메서드는 우리 라이브러리의 성패를 좌우할 가장 중요한 계약(Contract)입니다. 우리는 개발자들에게 ‘이 메서드 안에서는 이것만 하세요’라고 명확히 알려줘야 하고, 개발자들은 그 계약을 지켜야만 합니다.”

그 계약의 첫 번째 조항은 이미 정해졌다. ‘render는 순수해야 한다.’
이 메서드는 오직 버추얼 DOM 객체를 반환하는 일에만 집중해야 했다. 외부 세계에 영향을 주는 어떤 부작용도 허용되지 않았다.

크리스는 백본의 경험을 떠올리며 질문했다.
“백본의 render 함수는 보통 HTML 템플릿 문자열을 반환하고, 그것을 this.$el.html()을 이용해 직접 DOM에 삽입하는 구조였습니다. 우리 render는 버추얼 DOM 객체를 반환한다는 점 외에, 또 어떤 차이가 있죠?”

“가장 큰 차이는, 언제 호출되는가에 있습니다.” 조던이 대답했다. “백본에서는 개발자가 view.render()를 직접 호출해야 하는 경우가 많았습니다. 하지만 리액트에서는 개발자가 render를 직접 호출하는 일은 절대로 없습니다.”

이것은 매우 중요한 차이점이었다.
리액트에서 render의 호출은 전적으로 리액트 라이브러리 자신에게 맡겨져 있었다.

“리액트가 ‘아, 이제 화면을 다시 그려야 할 때가 왔군’이라고 판단하면, 그때 리액트가 알아서 컴포넌트의 render 메서드를 호출합니다. 개발자는 그저 render라는 약속된 이름의 메서드를 정의해놓기만 하면 되는 거죠. 마치 콜백 함수처럼요.”

이 설계는 개발자를 매우 편하게 만들어주었다. 언제 화면을 갱신해야 할지 고민할 필요가 없었기 때문이다. 하지만 동시에, render 메서드에 더 엄격한 제약을 가하는 이유이기도 했다. 리액트는 render가 언제, 몇 번 호출될지 보장하지 않는다. 성능 최적화를 위해 한 번의 업데이트 사이클 동안 여러 번 호출될 수도 있고, 반대로 호출되지 않을 수도 있다.

만약 개발자가 render 안에 화면을 그리는 것 외에 다른 로직(예: 데이터 요청)을 넣어두었다면, 그 로직이 예기치 않게 여러 번 실행되거나 아예 실행되지 않는 끔찍한 결과를 낳을 수 있었다.

“그렇다면 render 메서드 안에서 접근할 수 있는 데이터는 무엇이죠?” 맷이 물었다. “무엇을 기반으로 버추얼 DOM을 만들어야 합니까?”

조던은 화이트보드에 두 개의 단어를 적었다.

  1. props
  2. state

render 함수는 오직 이 두 가지 데이터 소스에만 의존해야 합니다. props는 부모 컴포넌트로부터 물려받는, 외부에서 주입되는 데이터입니다. 그리고 state는 컴포넌트가 스스로 관리하는, 내부적인 데이터죠.”

그는 <Greeting> 예제 코드를 수정하여 이 개념을 설명했다.

var Greeting = React.createClass({
  render: function() {
    // this.props.name 이라는 외부 데이터에 접근한다.
    var message = 'Hello, ' + this.props.name;
    
    return React.createElement('h1', null, message);
  }
});

// name="World" 라는 props를 전달하며 렌더링한다.
ReactDOM.render(
  React.createElement(Greeting, { name: 'World' }),
  document.getElementById('root')
);

이제 <Greeting> 컴포넌트는 더 이상 Hello, World!만 외치는 앵무새가 아니었다. 외부에서 name이라는 데이터를 주입받아, 그에 맞춰 동적으로 다른 메시지를 그려낼 수 있는 유연한 부품이 된 것이다.

render 메서드는 this.propsthis.state라는 두 개의 입력을 받아, 버추얼 DOM이라는 단 하나의 출력을 내놓는, 예측 가능한 블랙박스.
리액트의 핵심 철학이 render 메서드의 역할과 책임을 통해 명확하게 정의되고 있었다. 이제 팀의 다음 과제는 이 두 개의 데이터 소스, propsstate의 정체를 밝히는 것이었다.