우리가 class로 컴포넌트를 작성할 때 constructor를 작성하면 항상 super(props)를 적어줘야한다.

 

class Checkbox extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOn: true };
  }
  // ...
}

 

 

 

물론, constructor를 작성하지 않고 class fields를 작성하면 이러한 과정은 필요없이 간단하게 작성이 가능하다.

class Checkbox extends React.Component {
  state = { isOn: true };
  // ...
}

이렇게 적으면 리액트가 알아서 내부적으로 super(props)를 알아서 실행해주니 상관없지만

 

 

 

보다 근본적으로 class 컴포넌트를 이해하기 위해서 constructor 안에 super(props)를 써야하는 이유를 적어볼까 한다.

 

 

 

1. super()를 호출하지 않으면 어떻게 될까?

 

 

class Checkbox extends React.Component {
  constructor(props) {
    // 🔴 Can’t use `this` yet
    super(props);
    // ✅ Now it’s okay though
    this.state = { isOn: true };
  }
  // ...
}

우선 알아야 할 것이 있다.

 

Checkbox컴포넌트는 React.Component를 확장해서 만든 것이라는 점이다.

 

그런고로 React.Component의 this는 CheckBox의 this로 생각 할 수 있다.

먼저 super는 부모클래스 생성자의 참조이다.

 

즉, super는 React.Component의 constructor를 가리키는 것이다.

 

그리고 자바스크립트는 언어적 제약사항으로서 이런 extends가 사용되었을 때 super를 호출하기 전에는 this를 호출 할 수 없다.

 

 

 

 

어째서 이런 제약사항을 걸은 걸까? 여기에는 합리적인 이유가 있다.

아래의 예시를 보자.

 

class Person {
  constructor(name) {
    this.name = name;
  }
}


class PolitePerson extends Person {
  constructor(name) {
    this.greetColleagues(); // 🔴 This is disallowed, read below why
    super(name);
  }
  greetColleagues() {
    alert('My name is ' + this.name + ', nice to meet you!');
  }
}

 

 

super를 호출하기 이전에 this를 사용하는 것이 가능하다고 가정하면 이런 경우 코드를 이해하기 난해해진다.

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

PolitePerson의 constructor에서 this.greetColleagues();를 호출 했다.

 

greetColleagues매서드의 내용은  alert('My name is ' + this.name + ', nice to meet you!');이다. 

 

여기서 문제가 생긴다.

 

this.name은 부모컴퍼넌트인 Person안에 있는 내용이다. 

 

그래서 super(name)을 통해 불러와야 하는데 이 super(name)이 this.greetColleagues 밑에 있다.

 

즉, this.name을 불러오지도 못했는데 greetColleagues는 this.name을 불러오고 있는 것이다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

 

이렇게 애매한 경우를 허용하지 않기 위해서 자바스크립트는 언어 차원에서 this 사용 전에 super호출을 강제하는 것이다.

 

 

 

 

2. 왜 super()에다가 props를 인자로 전달해야 할까?

 

 

우선은 간단하게 설명하자면  super()안에 props를 넣는 이유는 React.Compoent도 역시 객체가 생성될 때

 

props 속성을 초기화하기 위해서다.

 

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

 

그러나 props 전달 없이 super()를 호출하더라도 render 함수 및 기타 메소드에서 여전히 this.props를 사용할 수 있다.

 

왜냐하면 리액트는 우리가 작성한 컴포넌트의 생성자 호출 이후 해당 객체에 props 속성을 세팅해주기 때문이다.

 

그래서 리액트는 props를 super의 인자로 전달하는 것을 실수로 빠뜨리더라도 정상적으로 동작되는 것을 보장해준다.

 

 

그렇다면 사람들은 그러면 리액트가 세팅해주는데 그냥 super()쓰면 되지 뭐하러 super(props)를 쓰냐고 생각할 수 있다.

하지만 잘 읽어보자 

 

'생성자 호출 이후'

 

 

즉, 그냥 super()라고 하면 생성자 호출 이후 이전인 '생성자 내부'에서는 this.props는 undefined가 될 것이다.

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(); // 😬 We forgot to pass props
    console.log(props);      // ✅ {} 예제라서 빈배열이라고 나와있지만 실제로 사용할 땐 많은 값이 들어있다.
    console.log(this.props); // 😬 undefined 
  }
  // ...
}

 

console.log(this.props) -> undefined가 나온다.

 

이것이 super(props)를 적어야 하는 이유다!

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

공부하는데 있어 한가지 헷갈리는 점을 유의하자.

 

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(props); 
    console.log(props);      // ✅ {} 예제라서 빈배열이라고 나와있지만 실제로 사용할 땐 많은 값이 들어있다.
    console.log(this.props); 
  }
  // ...
}

1. props는 '키:값'으로 이루어진 객체이다.

 

2. 여기서 constructor(props) , super(props), console.log(props)에 찍힌 props는 같은 props이지만

 

this.props에 있는 props는 다른 props다.

 

즉, 

 

// Inside React
class Component {
  constructor(props) {
    this.props = tt;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(tt) {
    super(tt); 
    console.log(tt);      // ✅ {} 예제라서 빈배열이라고 나와있지만 실제로 사용할 땐 많은 값이 들어있다.
    console.log(this.props); 
  }
  // ...
}

이렇게 해도 된다는 것이다.

 

tt객체에 들어온 값을 this.props 객체에  tt객체를 집어넣는거다!

 

 

 

 

 

 

 

 

 

+ Recent posts