읽기전

  • 첫 번역 블로그 글이며, 누군가에게 혹시나 도움이 될까 하는 마음에 올립니다. (번역을 하다보니 막상 제가 제일 많이 배우는것 같네요.😄) 직역보다는 의역에 중요성을 둠으로 원본글과 약간의 차이가 있을수 있지만 최선을 다해 원본의 내용을 옮겨보도록 하겠습니다.

시작

여기 function 형태로 만들어진 Greeting 이라는 콤포넌트가 있습니다.

image.png

React 에서는 이것을 class 형태로도 만들어볼수 있습니다.

image.png

(최근까지, 저 방법이 state 와 같은 기능을 사용할수 있는 유일한 방법이었습니다.)

당신이 Greeting 을 사용할때에는, 당신은 이것이 어떻게 만들어졌는지에는 관심이 없습니다.

image.png

하지만 React 안에서는 이 차이점(Function && Class)에 대해서는 중요하게 생각합니다. 만약에 Greeting 이 function 으로 만들어졌다면 React 은 아래와 같이 작동해야합니다.

image.png

그렇지만, Greeting이 Class 로 생성되었다면, React 은 new 오퍼레이터를 사용해서 instantiate 해야되고, 만들어진 instance 에 있는 render 메소드를 사용해서 호출해야합니다.

image.png

두 경우 전부 React 의 목표는 렌더링된 노드를 가져오는 것입니다(이 예제에서는 <p>Hello</p>). 하지만 그런 과정은 Greeting 이 어떻게 만들어졌는지에 따라 달라지게 됩니다.

그러면 React 는 어떻게 class 인지 function 인지 알수 있을까요?

예전 Post 와 마찬가지로, 당신은 이 부분에 대한 React의 생산성에 대해서 알 필요가 없습니다. 나 역시도 몇 년동안 알지 못했습니다. 부탁인데 이 부분을 인터뷰 질문으로 사용하지 말아주세요. 사실 이 글은 React 보다는 Javascript 에 관한 글입니다.

이 블로그는 React 이 어떻게 그러한 방법으로 작동하는지 궁금한 독자들을 위한 글입니다. 만약에 당신이 그러하다면, 같이 좀더 자세하게 알아봅시다.

이 글은 긴 여행이 될것입니다. 안전벨트 매세요. 이 글은 React 에 대해서 많은 정보를 담고 있지는 않지만, 우리는 new, this, class, arrow functions, prototype, __proto__, instanceof 에 대한 부분과 저런것들이 Javascript 에서 어떻게 작동하는지에 대해서 알아볼것입니다. 운이 좋겠도 당신은 React 를 사용할때에 저런것들에대해서 그다지 많이 알 필요가 없습니다. If you're implementing React though...(뜻은 알겠는데 정확하게 번역을 못하겠음)

(당신이 그저 답을 바로 알고 싶다면, 페이지 맨 아래로 스크롤하세요)

우선, 우리는 왜 Class 와 Function 을 다르게 다루어야 하는지 알아야합니다. class를 부를때 사용하는 new 오퍼레이터에 대해서 알아봅시다.

image.png

Javascript 에서 new 오퍼레이터가 무엇인지 단순히 추측해봅시다.

예전에는 Javascript 에서는 class 가 존재하지 않았습니다. 그렇지만 당신은 플레인 function 을 이용하여 class와 비슷한 패턴을 만들수 있었습니다. 구체적으로 당신이 어떤 function 을 사용하기전에 new 를 추가함으로써, class constructor 와 비슷한 역활을 하도록 사용할 수 있습니다.

image.png

오늘날에도 여전히 위의 방법처럼 사용할수 있습니다. DevTools 에서 한번 해보세요.

만약에 Person('Fred')new를 빼고 사용하였다면, Person 안의 this 는 어떤 global 이나 어떤 쓸모없는 무언가로 대체 될것입니다(예를 들면 window 또는 undefined). 그렇게되면 코드는 잘못작동하거나(crash), 의도하지 않은 어떤 멍청한(silly) 작업, 예를 들면 window.name 을 설정하는 일을 할것입니다.

function 을 호출시에 new를 붙임으로써,

"Hey Javascript! 내가 `Person` 이 function 인건 아는데, 이걸 한번 class constructor 라고 가정해보자! 
내가 `this.name` 와 같은 작업을 할수 있도록, `Person` 안에서 `this`에 새로운 {} object를 만들어서 그것을 `this` 에 
지정해줘(point)! 그다음에 그 object 을 나에게 반환해!"

라고 말하는것입니다. 이것이 new 오퍼레이터가 하는일입니다.

image.png

new 오퍼레이터는 우리가 Person.prototype 에 넣는 어떤것인듯 fred object 에 사용 가능하도록 만들어줍니다.
image.png

이것이 Javascript 에 Class 가 생기기 전의 사람들이 사용하던 방식입니다.

그래서 new 는 Javascript 안에서 존재해오고 있었지만, Class 가 최근에 등장하였고, Class 들은 위의 코드와 뜻이 통하도록 아래와 같이 작성하면 됩니다.

image.png

Capturing developer's intent is important in language and API design.
개발언어와 API 디자인에서 개발자의 의향를 파악하는것은 중요하다

만약에 function 하나를 작성한다면, Javascript 는 그 function 이 alert() 과 같이 호출될지, constructor 형태와 같이 new Person() 으로 호출될지 알수 없습니다. 앞에서의 Person 과 같은 function 에 new를 사용하지않는다면, 이것은 잘못된 결과를 이끌수 있습니다.

Class 의 사용은 "이 함수는 그저 단지 function 이 아니고, 이것은 class 이며 constructor 가 존재한다" 라고 말하는것과 같습니다. 만약에 Class호출시에 new 를 사용하지 않는다면 Javascript 는 에러를 발생합니다.

image.png

Class의 사용은 this.name 과 같은 코드가 george.name 이 아닌 window.name 으로 잘못 인식되는 부분을 좀더 빨리 찾을수 있도록 도와줍니다.

그렇지만 이 말은 즉, 어떤 class 를 사용하기도 전에 React에 new를 붙여야 한다는것입니다. 이부분을 Javascript 에서 에러처리함으로써 React 을 regular function 과 같이 사용할수 없습니다.

image.png

우리는 React 에서 이부분을 어떻게 해결하는지 알기 전에, 대부분의 사람들이 React 을 사용할때 Babel 과 같은 컴파일러를 사용하여 최신 기능들을 옛날 브라우저에도 작동하도록 변환하여 사용합니다. 그래서 우리는 이런 컴파일러들을 우리의 디자인에 포함하여 생각해야 합니다.

초기 버전의 Babel에서는 Class 들을 new 를 빼고도 사용 가능하였습니다. 하지만 이부분은 다음과 같은 코드가 추가적되는것으로 수정되었습니다.

image.png

번들파일*에서 위와 같은 코드를 볼수 있었을 것입니다. (번들파일 = webpack 이나 babel 로 컴파일된 결과물) 그것은 전부 _classCallCheck 가 하는일입니다. (loose mode 를 사용하여 검사를 하지 않도록 하여 bundle 사이즈를 줄일수 있으나, 이것은 native classes 의 궁긍적인 변환에 문제가 발생할수 있습니다)

지금까지 new 를 사용하여 부를때와 new를 사용하지 않고 부를때의 차이점을 간단하게 알아보았습니다.

image.png

이부분이 React 으로 하여금 당신의 component 를 정확하게 호출하는것이 중요한 이유입니다. 만약에 당신이 class 를 사용하였다면 React 은 이것을 부를때 new 사용하여만 합니다.

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

(내용이 길어서 2편으로 나누어서 번역할께요)

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