본문 바로가기
Javascript/React 지식

[React] 클래스형 컴포넌트

by isfp_yykkng 2023. 4. 23.

클래스형 컴포넌트

클래스형 컴포넌트란

클래스형 컴포넌트는 생명 주기 함수와 컴포넌트의 구성 요소들을 모두 포함하고 있는 컴포넌트로 2가지 클래스 종류인 Component, PureComoponent 가 있다.

  • Component 클래스 : 프로퍼티, state와 생명주기 함수가 들어있는 구조의 컴포넌트를 만들 때 사용한다. 우리가 일반적으로 클래스형 컴포넌트를 사용할 때 사용한다. PureComponent 클래스와 다르게 Compoenent 클래스로 만들어진 컴포넌트는 항상 (무조건) render() 함수를 호출한다. 
  • PureComponent 클래스 : 바로 위에서 설명한 Component  클래스를 상속받은 클래스로 약간의 차이점이 있다. 그 차이점이 바로 shouldComponentUpdate() 함수를 " 얕은 비교 " 를 하도록 재정의 한 점이다. PureComponent 클래스로 만들어진 컴포넌트는 얕은 비교를 통해 데이터가 변경된 경우에만 render() 함수를 호출한다.

PureComponent의 shouldComponentUpdate() 함수 재정의 모습

얕은 비교를 위해서 shallow-equal 라이브러리의 shallowEqual()함수를 사용한다. shallow-equal 라이브러리를 사용하기 위해서 터미널에 " npm install -g shallowequal " 이나 " yarn add shallow-equal " 명령어를 입력해야한다.

import React, { Component } from "react";
import shallowEqual from 'shallow-equal';

export class PureComponent extends Component {
    shouldComponentUpdate(nextProps, nextState) {
    	return !shallowEqual(this.props, nextProps) ||
               !shallowEqual(this.state, nextState);
    }
}

위 코드의 return 값을 보면 shallowEqual() 함수를 통해서 현재와 갱신한 props와 state를 얕은 비교하여 바뀐 것이 있으면 두 값이 다르기 때문에 false가 나오고 그 값에 대한 not 연산으로 true를 만든다. 즉, props나 state 둘 중 하나라도 얕은 비교에 의해 바뀐 것이 있으면 shouldComponentUpdate() 함수의 반환값으로 true를 반환하여 render() 함수를 호출하는 구조이다.

 

[참고] ==, ===, shallowEqual() 함수 비교

- 깊은 비교 : ==, ===

- 얕은 비교 : shallowEqual() 함수

Component와 PureComponent 비교 예제

...
    constructor(props){
    	super(props);
        this.listValue=[ {name : 'Park'}, {name : 'Lee'} ];
        this.state = { version : 0 };
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick() {
        setTimeout(()=> {
            this.listValue[0] = 'Justin';
            this.setState({version : 1});
    	}, 2000); //2초 후
        setTimeout(() => {
            this.listValue = [ {name : 'Justin'}, {name : 'Lee'} ];
            this.setState({version : 2});
        }, 4000); //4초 후
    }
    render(){
    	return(
            <div>
            	<button onClick={this.handleClick}>버튼</button>
 
 ...

코드의 결과로 2초 후에는 Component만 render()를 호출하여 바뀐 값이 없고, 4초 후에는 Component와 PureComponent 모두 render()를 호출하여 바뀐 값이 있었다. 다음 비교를 하면 쉽게 이해할 수 있다.

import shallowEqaul from 'shallow-equal';

const obj = { name : 'park' };
const mylist = [ 1, 2, 3, obj ];
const list1 = [ 1, 2, 3, obj ];
const list2 = [ 1, 2, 3, { name : 'park' } ];

console.log(mylist === list1);  //false
console.log(shallowEqual(mylist, list1));  //true ⭐
console.log(shallowEqual(list1, list2));  //false ⭐

깊은 복사 '===' 이나 '==' 의 경우 같은 요소를 가지고 있더라도 각자 새롭게 정의된 배열이라면 변수를 담고 있는 주소가 다르기 때문에 false를 반환한다. 하지만 얕은 복사 shallowEqual() 함수는 내용물들을 모두 보지 않고 비교한다. 두 변수가 가지고 있는 데이터의 형태가 똑같다면 true 인 것이다. mylist와 list1은 모두 [ 1, 2, 3, obj ] 의 형태를 가지고 있지만, list2는 [1, 2, 3, { name : 'park'} ] 이란 형태로 다르기 때문에 false가 나온 것이다.

 

* shallowEqual() 함수에 대한 이해가 아직은 부족합니다. 댓글로 틀린 부분을 알려주세요! 😂