리액트로 첫 프로젝트를 하면서 학교 선배에게 코드 리뷰를 부탁드렸는데, 선배가 코드를 보더니 한숨을 쉬시면서 내게 질문 한가지를 하셨다.
"너 컴포넌트와 퓨어컴포넌트의 차이가 뭔지 알아?"
"...몰라욘"
"...공부해"
퓨어컴포넌트가 뭘까? 순수한 컴포넌트인가? 순수하면 뭐가 좋은거지? 조금 더 빠르다고 들은 것 같긴한데... 이 때까지는 정확한 정의를 몰랐다.

image.png

PureComponent와 Component의 차이

React.PureComponent는 사실 React.Component와 비교해서 딱 한가지만 다르다! 그것은 바로 shouldComponentUpdate를 어떻게 쓰는가 하는 부분이다.

자 그러면 이제, React.ComponentReact.PureComponent가 각각 어떻게 컴포넌트 업데이트 여부를 결정하고 컴포넌트를 업데이트하는지 확인해보도록 하자.

React.Component

import React, { Component } from 'react';

class BlahBlah extends Component {
  state = {
    count: 0
  }
  counter () {
    this.setState({
      count: this.state.count // 주목! 값이 변경되지는 않으나, setState는 써줌!!
    })
  }
  componentDidUpdate () {
    console.log(this.state.count); // 컴포넌트가 업데이트되면 값을 출력시킨다.
  }
  render () {
    return (
      <div> 
        { this.state.count }
        <button onClick={this.counter.bind(this)}>counterButton</button>
      </div>
    )
  }
}

export default BlahBlah;

이렇게 작성한 뒤 브라우저에서 콘솔창을 열고 counterButton을 광클해보자.

image.png

React.Component는 결론적으로 shouldComponentUpdate를 따로 설정해주지 않은 경우, 항상 true를 반환한다. setState가 실행되면 state, props의 변경 여부를 신경쓰지 않고 무조건적으로 컴포넌트를 업데이트시킨다는 것이다.

그렇기 때문에 위의 코드에서는 count의 값은 변경되지 않았지만, setState가 실행되었기 때문에 컴포넌트 업데이트가 일어나 componentDidUpdate가 실행된 모습이다.

그렇다면 React.PureComponent에서는 어떨까? 위 코드에서 ComponentPureComponent로 바꾸어주면 된다.

React.PureComponent

import React, { PureComponent } from 'react';

class BlahBlah extends PureComponent {
  state = {
    count: 0
  }
  counter () {
    this.setState({
      count: this.state.count // 주목! 값이 변경되지는 않으나, setState는 써줌!!
    })
  }
  componentDidUpdate () {
    console.log(this.state.count); // 컴포넌트가 업데이트되면 값을 출력시킨다.
  }
  render () {
    return (
      <div> 
        { this.state.count }
        <button onClick={this.counter.bind(this)}>counterButton</button>
      </div>
    )
  }
}

export default BlahBlah;

위와 같이 ComponentPureComponent로 변경해준 후 다시 한 번 콘솔창을 열고 counterButton을 광클해보자. 콘솔창에 아무 것도 나타나지 않을 것이다. 값이 변경되지 않았으므로, 컴포넌트 업데이트는 일어나지 않는다.

그렇다면 PureComponent정확히 언제 어떻게 컴포넌트 업데이트를 수행하는 것일까?

얕은 비교 (shallow-compare)

PureComponentshouldComponentUpdate에서 얕은 비교를 통해 업데이트 여부를 결정한다.

얕은 비교란 무엇일까? 얕은 비교의 특징은 다음과 같다.

  • 변수와 문자열에서는 값을 비교한다.
  • Object에서는 reference값을 비교한다.

PureComponent는 위의 조건으로 현재 state, props와 바뀔 state, props를 비교하여 업데이트 여부를 결정하게 되는 것이다. 그렇기 때문에 위의 코드에서 setState는 실행되었지만, count의 값이 바뀌지 않아 컴포넌트가 업데이트되지 않았다!

언제 쓰는게 좋을까?

다음은 내 개인적인 Thinking이다.

  • 따로 shouldComponentUpdate를 만지지 않아도 되거나 만지고 싶지 않을때
  • 일단 PureComponent로 써보고 안되겠다 싶으면 Component를 쓴다