Dan Abramov - How does React tell a Class from a Function? (2편)

Billy Kang·2018년 12월 30일
2
post-thumbnail

읽기전

시작

그러면, React 은 무언가를 호출할때 class인지 검사를 할까요?

이부분은 쉽지 않습니다. 우리가 class와 Javascript 의 function을 구분할수 있더라도, Babel과 같은 도구로 실행되는 부분에는 적용되지 않습니다. 브라우저에서 classes은 그저 plain function 입니다. React 한테는 운이없네요.

그러하다면, 아마 React은 모든 호출에서 new 를 그냥 호출하는게 아닐까요? 안타깝게도 그렇지도 않습니다.

일반적인 functionsnew 로 호출하면은 object instance 와 같은 this 를 반환합니다. 이것은 constructor 용도로 사용한 functions 한테는 바람직하지만, function 콤포넌트들에게는 혼동을 가져올수 있습니다.

image.png

모 이런점은 어느정도 참을수 있는 부분이긴 합니다. 이 의견을 막는 다른 두 이유가 있습니다.

new를 항상 부를 없는 첫번째 이유는 바로 native arrow functions(Babel 로 compile 되지 않은)때문입니다. 이것들을 new를 사용하여 호출하면 에러가 발생합니다.

image.png

이런 결과는 의도된것이며 arrow functions 의 디자인을 따른것입니다. arrow functions의 하나의 장점은 이것들은 자신들의 this를 가지고 있지 않다는 것이며, 나아가, this가 가장 가까운 일반적인 function 에 녹아든다는 것입니다.

image.png

그럼 arrow functions는 그들만의 this 를 가지고 있지 않다는 말은 즉, 그들은 constructor 로써 완전히 쓸모가 없다는 것을 뜻합니다.

image.png

그러므로 Javascript 는 arrow functionnew를 사용하여 부르는것을 허용하지 않습니다. 혹시 당신이 그렇게 하고 있다면 잘못하고 있는것입니다. 잘못된것은 일찍 말해주는것이 최선입니다. 이것은 Javascript 가 classnew를 사용하지 않고 부를수 없는것과 비슷한 부분입니다.

이런 건 좋은 부분이지만 우리의 계획을 지지하지는 않습니다. React은 모든 부분에서 항상 new를 사용할수는 없습니다. 그렇게 하면 arrow functions 들을 망쳐버리기 때문입니다. 우리는 arrow functionsprototype 이 부족하다는 점을 이용하여 그것들만 찾아서 new 를 사용하지 않도록 해볼수도 있습니다.

image.png

하지만 Babel에 의해서 컴파일되는 function 들은 적용되지 않습니다. 이 부분은 대단한건 아닙니다만, 이런 시도를 끝내야만 하는 또 다른 이유가 있습니다.

우리가 항상 React 에서 new를 사용할 수 없는 또 다른 이유는 React 이 String이나 다른 기초 타입을 반환하는 컴포넌트들을 지원할수 없게 되기 때문입니다.

image.png

이건 다시 반복하자면, new 오퍼레이터 디자인의 별난 부분과 관련이 있습니다. 우리가 앞에서 본것처럼, new은 Javascript 엔진에게 object 을 생성하고 그 object 을 function 의 this와 연동하고 그 object 을 new의 결과값으로 우리에게 리턴합니다.

그렇지만 Javascript는 new를 사용하여 호출된 functions의 반환되는 new의 값을 다른 object을 반환하도록 override 하는것을 허용합니다. 짐작컨데 이런 점은 우리가 instance들을 재사용하는 pooling 과 같은 패턴에서 유용합니다.

image.png

그렇지만 new 또한 function 의 반환값이 object 이 아니면 완전히 무시해버립니다. 당신이 만약에 String이나 number 를 반환한다면 그건 반환되는 값이 하나도 없는것과 마찬가지입니다.

image.png

function 을 new로 사용하여 호출하였을때 이것의 기초 타입(numberString과 같은)의 반환값을 읽을수 있는 방법이 없습니다. 그러므로 React 이 항상 new를 사용한다면 String 타입을 반환하는 콤포넌트들은 지원할수 없게 됩니다.

이 부분은 받아들일수 없는 부분이므로 우리는 타협할 필요가 있습니다.

지금까지는 우리는 무엇을 배웠나요? React 은 classes(Babel 컴파일 결과물을 포함한)를 new로 호출할 필요가 있으며, 일반적인 function들은 new를 사용가능하고, arrow functionsnew를 사용하면 안된다는것을 배웠습니다. 그리고 그것들을 구별할 수 있는 믿음직한 방법은 없습니다.

그럼 우리가 일반적인 문제를 해결할수 없다면 좀더 구체적인 것을 해결할수 있을까요?

당신이 컴포넌트 하나를 class형식으로 만들때 보통 this.setState() 와 같이 제공되는 built-in 함수를 사용하기 위해 React.Component를 사용할 것입니다. 그러므로 React의 모든 classes를 찾아보는 것보다, React.Component와 하위 요소들만 찾아봐도 되겠죠?

스포일러: 지금부터 설명하는 것이 정확하게 React가 하고 있는것입니다. (👈 제가 추가한거 아니고 원본에 있는 내용입니다)

(내용이 길어서 3편으로 나누어야 할듯 싶습니다. 3편에서 마무리하도록 할께요.)

profile
새로운것에 관심이 많은 개발자

0개의 댓글