[잔뿌리 호기심]은 잔뿌리처럼 메인 주제에서 뻗어 나온 개인적인 궁금증을 다룹니다.
React 에서의 this
Javascript 의 중요한 개념 중 하나인 this를 잘 모르는 나의 무지함에 부끄러움을 느끼고,
동시에 this를 잘 알고싶다는 지적 허영심을 채우고자 여기서 관심이 많다는 말을 했었다.
( 뭔가 this 키워드를 쓰는걸 보면 멋있어 보이더라. )
실제로 다른 라이브러리에서의 코드에서는 심심찮게 this 키워드를 볼 수 있었지만, 내가 사용할 일은 없었다.
나도 this를 맛있게 써서 멋있어보이고 싶었다!!
React에서 this는 어떻게 사용될까? 왜 나는 React에서 this를 사용하지 않았을까?
함수형 컴포넌트와 클래스형 컴포넌트
React 에서의 This를 알아보기 앞서서 조금 더 먼저 짚고 넘어가야 할 키워드가 있다.
React에서 사용되는 두 가지 스타일의 컴포넌트인 클래스형 컴포넌트와 함수형 컴포넌트다.
흔히 알고있는 클래스형 컴포넌트와 함수형 컴포넌트의 차이라고 한다면
과거엔 클래스형 컴포넌트에서만 생명주기 메서드들을 사용할 수 있었지만,
현재엔 함수형 컴포넌트에서도 React Hook을 활용하여 사용할 수 있게 되었다.
정도가 있겠지만, 오늘 작성 할 내용인 this의 활용법에 대해서도 추가하면 좋겠다.
물론 이 외에도 클래스형 컴포넌트는 객체지향 프로그래밍의 특징인 상속이나 추상화등을 강점으로 가지고있다.
최근 React 생태계에서는 함수형 컴포넌트가 절대적 주류라는 점은 누구도 부정할 수 없는 사실일 것이다.
나도 Javascript를 사용하고 얼마 지나지 않아 React를 처음 접할때 함수형 컴포넌트가 기본값인 줄 알고 사용했다.
조금 특이한 점은 Vanilla JS를 사용할 땐 어렵지 않게 볼 수 있었던 this키워드가 React를 사용하며 극단적으로 줄었다. 나는 단순히 이것이 내가 개발을 잘 못해서 그런 것 이라고만 생각해왔다.
물론 아직 못하는것도 사실이지만, 그것을 넘어서 함수형 컴포넌트에서는 사용하지 않는 이유가 있기 때문도 있다.
그 이유에 대해서 오늘 한번 알아보자.
this 바인딩
가장 먼저 각 컴포넌트에서 this가 바인딩되는 조건에 대해서 생각해보자.
함수에서의 this바인딩은 대략 5가지정도로 요약해 볼 수 있다.
- 생성자 호출
- 메서드 호출
- 일반 함수 호출
- apply, bind, call 호출
- arrow function 호출
그렇다면 각 컴포넌트의 바인딩은 어떻게 결정될 지 한번 고민해보자.
클래스형 컴포넌트
클래스형 컴포넌트에서의 this는 Class 라는 키워드 자체가 Javascript에서 prototype 상속의 syntax sugar 로 평가되는 만큼, 생성자 함수로서 호출될 때와 동일하게 컴포넌트 인스턴스에 바인딩 될 것이라고 추측해볼 수 있다.
(실제로도 그렇다)
함수형 컴포넌트
함수형 컴포넌트에서의 this바인딩은 앞선 다섯가지 구분중에서 어느 부분에 해당할까?
function 키워드를 사용한 함수선언문이라면, 일반 함수 호출. arrow function 을 사용한 화살표 함수는 arrow function 호출 을 따라가게 된다.
하지만 arrow function 를 사용한 함수형 컴포넌트에서 this를 사용하는것은 조금 옳지 못하지 않나 싶다.
화살표함수의 this 바인딩은 상위 스코프에 렉시컬하게 바인딩되기 때문에 개발자가 사용하기엔 조금 복잡할 수 있다고 생각하기 때문이다.
따라서 function키워드를 사용한 경우만 따져보려 하는데, 일반함수에 경우엔 전역객체가 바인딩 될 것이라고 추측해볼 수 있다. (실제로는 다르다)
실제로는
undefined가 바인딩 되는 것을 확인해볼 수 있다.
이 부분은 바로 밑에서 조금 더 자세히 알아보겠다.
중간점검
지금까지의 내용을 정리하자면 다음과 같다.
- 클래스형 컴포넌트는 this 가 컴포넌트 인스턴스에 바인딩되어 일반적으로 this가 활용되는 구조와 유사하며 실제로 활발하게 사용된다.
- 하지만 함수형 컴포넌트에서는 아직까진 전역객체가 바인딩 될 것이라고 추측해볼 수 있으며, 이것은 this를 활용하기엔 어려워 보인다.
여기까지 봤을 땐, 내가 this를 잘 보지 못하고 사용하지 않았던 이유는 함수형 컴포넌트를 사용했기 때문이라고 추측할 수 있다.
함수형 컴포넌트와 this
함수형 컴포넌트에서는 왜 this키워드를 사용할 수 없었던 것일까?
기술적(?) 이유
기술적인 이유로는 앞서 전역객체가 바인딩 될 것이라고 추측해보았지만, 실제로 this키워드를 사용해보면 undefined 가 바인딩된다. 그 이유는 React 내부의 컨텍스트에서는 대부분의 환경이 strict mode를 사용하기 때문이다.
그래서 클래스 컴포넌트에서는 This를 바인딩해서 사용할 수 있는 반면, 함수형 컴포넌트 내부에서의 this는 undefined 바인딩되기 때문에 사용할 수 없다.
개념적 이유
개념적인 이유로는 this키워드와 일반함수와의 관계와 마찬가지로 엮일 수 없는 위치에 존재한다는 점이다.
과거 모던 자바스크립트 스터디 - this 에서 알아봤듯이 this 키워드의 존재 이유는 인스턴스의 메서드가 프로퍼티에 접근하기 위한 자기참조변수 역할을 하기 위해서다.
하지만 메서드가 아닌 일반함수는 인스턴스로 존재하지 않기 때문에 this 키워드의 존재의미 또한 흐릿해진다.
이러한 이유들로 함수형 컴포넌트에서의 this 키워드는 기술적으로, 개념적으로 활용하기에 적합하지 않아 대다수의 사람들이 사용하지 않았고 자연스럽게 새롭게 기술을 배우게 된 나 또한 활용하지 않게 되었다… 정도로 귀결될 것 같다.
컴포넌트에서의 this
클래스형 컴포넌트에서는 주로 상태(state)관리를 위해 사용됐다. 상태, 메서드 정의, 속성(Props) 접근을 위해 this키워드를 활용했다.
this키워드를 여러가지 이유로 사용할 수 없게 된 함수형 컴포넌트에게도 상태관리를 위해 무언가 보상의 차원에서 기능을 제공해야 할 것으로 보인다.
이것을 해소해주기 위한 방법이 바로 useState, useEffect 와 같은 React Hooks다. 즉, 간편하게 사용해왔던 React-Hook들이 사실 this키워드를 대체하기 위해 보상 차원으로 추가된 존재하는 요소들이라고 이해할 수 있다.
결론
내가 함수형 컴포넌트에서 this키워드를 자주 접하지 못하는 것은 어느정도 자연스러운 결과였던 것 같다.
실제로 함수형 컴포넌트에서 this키워드를 대체해주는 다양한 React-Hook들을 활용했고 그 과정에서 this의 부재로 인한 불편함을 느끼지 못했다.
다만, 알고서 사용하지 않는것과 몰라서 사용하지 못하는건 큰 차이가 있는것임에도 이제서야 알고싶어 한 내가 조금 부끄러워질 뿐이다.
잔뿌리 호기심
이 글을 위해 공부하며 새롭게 생긴 호기심에 대한 글을 쓸 예정입니다.
- [TODO…] 함수형 컴포넌트는 뭐가 예쁘다고 React Hook까지 만들어가면서 사용하게 되었을까?
