TIL14, React: super() 에 대해

sunghoonKim·2020년 12월 3일
2

클래스형 컴포넌트를 만들 때 가끔은 컨스트럭터가 있고, 가끔은 컨스트럭터가 없던데 왜 그런거야? 도대체 super()는 뭐야?

언제 컨스트럭터에서 super()를 써주어야 하는지 한번 짚고 간다. (여기 를 참조)


12/17, 수정!

이 전에는 super() 를 클래스 안에서 this 를 사용하기 위해서 호출해 주어야 한다고 했었다. 정정한다. 아니다. super() 를 호출해 주는 이유는, constructor 안에서 this 를 사용하기 위해서 이다. constructor 를 호출 하지 않아도 클래스 내부에서 this 를 사용하는데 아무 문제 없다.

constructor 를 호출하지 않고 state 를 사용하려면, 아래와 같이 구성을 하면 된다.

import React from 'react';

class App extends React.Component {
  state = {
  	haha: "haha"
  }

  render() {
    return (<div>{this.state.haha}</div>);
  }
}

export default App;

처음 리액트를 배울 때, 클래스형 컴포넌트로 시작을 하였고, 보이는 대부분의 기초 예제에서는 constructor 를 호출한 뒤, constructor 안에서 state 를 선언하였다. 그래서 단순하게 무조건 선행되어야 하는 부분인가 보다 하고 생각을 하고 있었다. constructor 가 항상 선행된 이유는, 리액트의 Life Cycle에 대해 이해시키려고 그랬던 것 같다. Life Cycle은 항상 constructor 에서 부터 시작하니까 말이다.

아무튼, 그렇단다.


## `super()` 팀원들 코드를 살짝 엿보면서 혼란스러운 부분을 마주했다. 다 같은 클래스형 컴포넌트인데, 몇몇 컴포넌트는 `super()` 가 선언되고, 다른 몇몇 컴포넌트는 그렇지 않았다는 점. 그 차이가 무엇으로 인해 생기는 것일까.

super() 호출이 필요한 경우

기본적으로 constructor 를 선언해서 super() 를 사용하는 이유는, 컨스트럭터 안에서 this를 사용하기 위함이다. 확인하고 싶다면, super()를 호출하지 않고, this를 사용해보면 알 수 있다.

import React from 'react';

class App extends React.Component {
  constructor() {
    this.state = {
      haha: "haha"
    }
  }
  render() {
    return (<div>{this.state.haha}</div>);
  }
}

export default App;

위의 코드는 아래와 같은 오류 메세지를 나타낸다.

this 를 통해 state에 접근하려면 먼저 super()constructor 안에서 호출해주는 과정을 거쳐야 한다.

constructor()를 호출할 필요가 없는 경우

state를 사용하는 것이 아닐 경우 이다. 이런 경우는 1. 단순하게 순수 html만 렌더링 하는 경우이거나 2. 부모로 부터 받은 props 만 사용하는 경우가 있다.

내가 헷갈렸던 경우가 두번째 경우인데, 넘겨 받은 props 에 접근하기 위해 this.props 를 통한다. this 키워드를 사용하는데 constructor 를 호출하지 않아도 된다고?

그렇다. props 에 접근할 때 사용하는 thissuper() 를 호출해줄 필요가 없다.

// 상위 컴포넌트
class App extends React.Component {
  constructor() {
    super();
    this.state = {
      str: "this is the test string!"
    }
  }
  render() {
    return (<Main test={this.state.str} />);
  }
}

// 하위 컴포넌트
class Main extends React.Component {
    render() {
        return (<div>{this.props.test}</div>);
    }
}

아무 문제 없이 this is the test string 라는 텍스트가 출력된다.

(+ 클래스 내에 정의된 함수를 호출할 때 사용하는 this 또한 super() 를 선행하지 않아도 된다.)

정리

클래스형 컴포넌트에서 컨스트럭터를 호출할 때와 그렇지 않을 때의 구분을 정리해보았다.

  1. 컴포넌트가 state를 가지고 있을때, 해당 state 에 접근 / 호출할 때 사용하는 thiscontructor 를 통해 super() 를 호출하는 과정이 선행 되어야 한다.
  2. 컴포넌트가 state를 가지지 않는 경우, super()를 호출해 줄 필요가 없다. state가 없다함은, 부모에서 넘겨받은 props만 사용한다는 의미인데, 그때 사용하는 this 는 아무런 문제 없이 호출할 수 있다.

개념을 그냥 머릿속에만 두고 이해하려 하면, 그 실체가 뚜렷하게 보이지 않아 막연하게 복잡하고 어렵게 느껴진다. 확실히 글을 통해 정리를 하니, 흐릿하던 개념들이 선명하게 보이고 그 관계도가 명확해진다. 잘 모르겠을 땐, 머리 쥐어잡지 말고 그냥 써보자. 젭알.

0개의 댓글