리액트로 첫 프로젝트를 하면서 학교 선배에게 코드 리뷰를 부탁드렸는데, 선배가 코드를 보더니 한숨을 쉬시면서 내게 질문 한가지를 하셨다.
"너 컴포넌트와 퓨어컴포넌트의 차이가 뭔지 알아?"
"...몰라욘"
"...공부해"
퓨어컴포넌트가 뭘까? 순수한 컴포넌트인가? 순수하면 뭐가 좋은거지? 조금 더 빠르다고 들은 것 같긴한데... 이 때까지는 정확한 정의를 몰랐다.
React.PureComponent
는 사실 React.Component
와 비교해서 딱 한가지만 다르다! 그것은 바로 shouldComponentUpdate
를 어떻게 쓰는가 하는 부분이다.
자 그러면 이제, React.Component
와 React.PureComponent
가 각각 어떻게 컴포넌트 업데이트 여부를 결정하고 컴포넌트를 업데이트하는지 확인해보도록 하자.
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을 광클해보자.
React.Component
는 결론적으로 shouldComponentUpdate
를 따로 설정해주지 않은 경우, 항상 true
를 반환한다. setState
가 실행되면 state, props의 변경 여부를 신경쓰지 않고 무조건적으로 컴포넌트를 업데이트시킨다는 것이다.
그렇기 때문에 위의 코드에서는 count의 값은 변경되지 않았지만, setState
가 실행되었기 때문에 컴포넌트 업데이트가 일어나 componentDidUpdate
가 실행된 모습이다.
그렇다면 React.PureComponent
에서는 어떨까? 위 코드에서 Component
만 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;
위와 같이 Component
를 PureComponent
로 변경해준 후 다시 한 번 콘솔창을 열고 counterButton을 광클해보자. 콘솔창에 아무 것도 나타나지 않을 것이다. 값이 변경되지 않았으므로, 컴포넌트 업데이트는 일어나지 않는다.
그렇다면 PureComponent
는 정확히 언제 어떻게 컴포넌트 업데이트를 수행하는 것일까?
PureComponent
는 shouldComponentUpdate
에서 얕은 비교를 통해 업데이트 여부를 결정한다.
얕은 비교란 무엇일까? 얕은 비교의 특징은 다음과 같다.
PureComponent
는 위의 조건으로 현재 state, props와 바뀔 state, props를 비교하여 업데이트 여부를 결정하게 되는 것이다. 그렇기 때문에 위의 코드에서 setState
는 실행되었지만, count의 값이 바뀌지 않아 컴포넌트가 업데이트되지 않았다!
다음은 내 개인적인 Thinking이다.
shouldComponentUpdate
를 만지지 않아도 되거나 ~만지고 싶지 않을때~