// 과거
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
counter: 0
};
}
...
}
// 요즘
class Counter extends Component {
state = {
counter: 0
};
...
}
리액트 클래스형 컴포넌트를 사용할 때,
예전에는 constructor
내부에서 this.state
를 설정해야 했는데
요즘은 constructor
없이 바로 state
를 사용할 수 있는 이유가
class-properties
문법 덕분이었다.
class-properties는 mdn에서 Class fields와 같은데
JS에서는 아직 표준은 아니고 실험적단계(stage3)이다.
CRA에서는 babel을 사용해서 class-properties 문법을 지원하기 때문에
리액트에서 바로 사용할 수 있었던 것이다.
babel 문서를 살펴보자.
class Bork {
//Property initializer syntax
instanceProperty = "bork";
boundFunction = () => {
return this.instanceProperty;
};
//Static class properties
static staticProperty = "babelIsCool";
static staticFunction = function() {
return Bork.staticProperty;
};
}
let myBork = new Bork();
//Property initializers are not on the prototype.
console.log(myBork.__proto__.boundFunction); // > undefined
//Bound functions are bound to the class instance.
console.log(myBork.boundFunction.call(undefined)); // > "bork"
//Static function exists on the class.
console.log(Bork.staticFunction()); // > "babelIsCool"
위에서 class 내부에 바로 선언한 프로퍼티의 경우,
인스턴스 객체 myBork
의 인스턴스 프로퍼티가 된다!
이전 글에서처럼 프로토타입을 그려보자면 다음과 같다.
(프로토타입 프로퍼티와 헷갈렸는데
class 내부에서 바로 선언한 프로퍼티 = 인스턴스 프로퍼티
static 프로퍼티 = 정적 프로퍼티
Bork.prototype.- 으로 작성해줘야 프로토타입 프로퍼티이다.)
이때, babel이 컴파일 하는 두가지 방법이 있는데
{ "setPublicClassFields": true }
라면 assignment표현식
을
아니라면 Object.defineProperty
을 사용한다.
// assignment expressions 사용
var Bork = function Bork() {...};
Bork.a = "foo";
// Object.defineProperty 사용
Object.defineProperty(Bork, "a", {
configurable: true,
enumerable: true,
writable: true,
value: "foo",
});
class Bork {
//Property initializer syntax
instanceProperty = "bork";
boundFunction = () => {
return this.instanceProperty;
};
//Static class properties
static staticProperty = "babelIsCool";
static staticFunction = function() {
return Bork.staticProperty;
};
}
let myBork = new Bork();
//Property initializers are not on the prototype.
// 프로토타입 메서드라, 인스턴스 메서드이다!!!
console.log(myBork.__proto__.boundFunction); // > undefined
//Bound functions are bound to the class instance.
console.log(myBork.boundFunction.call(undefined)); // > "bork"
//Static function exists on the class.
console.log(Bork.staticFunction()); // > "babelIsCool"
myBork.boundFunction.call(undefined)
에서 왜 call(undefined)를 하는지 이해가 안가서
명세랑, mdn을 찾아보았다.
NOTE2 에서 화살표함수인 경우 thisArg는 step4에서 무시된다고 나와있다.
맞다. 화살표함수(mdn)는 this바인딩이 없어
call, apply, bind method를 사용할 수 없었다(효과x).
화살표함수에서 this를 사용하면 렉시컬스코프의 this가 사용될 뿐..
call, apply 사용할 경우 this는 무시되고
인자만 전달할 수 있다.
예시에서 call(undefined)를 한 이유는,
this가 myBork 인스턴스에 바인딩되어있는걸 보여주기 위해서였다.