React Component를 작성할 때, 함수형 컴포넌트를 작성하지 않는다면 JS Class를 사용해 컴포넌트를 작성한다.
그러나, Class는 ES6에 나온 문법이고, 모종의 이유로 ES6로 작성하길 꺼리는 상황이 올 수가 있다.
그럴 땐, create-react-class 패키지를 사용하면 된다.
var createReactClass = require('create-react-class');
var Greeting = createReactClass({
render: function() {
return <h1>Hello, {this.props.name}</h1>;
}
});
몇가지 예외 사항을 제외하곤 createReactClass는 ES6 class API 와 비슷하다. 이를 살펴보겠다.
class Component는 해당 컴포넌트 내부에서 default Props 속성을 가지고 있다.
createReactClass()는 getDefaultProps() 에 object를 넘겨줘야 한다.
class Greeting extends React.Component {
// ...
}
Greeting.defaultProps = {
name: 'Mary'
};
var Greeting = createReactClass({
getDefaultProps: function() {
return {
name: 'Mary'
};
},
// ...
});
ES6 Class에선, constructor 내부에 this.state를 통해 초기 상태를 정의할 수 있다.
createReactClass()는 getInitialState 메소드에 넘겨줘야 한다.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: props.initialCount};
}
// ...
}
var Counter = createReactClass({
getInitialState: function() {
return {count: this.props.initialCount};
},
// ...
});
ES6 클래스로 React component를 선언하는 경우, 메소드는 일반적인 ES6 클래스 문법을 따라가게 된다.
클래스는 instance에 자동적으로 this를 바인딩 하지 않으므로, constructor에 .bind() 문법을 명시적으로 사용해줘야 한다.
class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'Hello!'};
// This line is important!
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.state.message);
}
render() {
// Because `this.handleClick` is bound, we can use it as an event handler.
return (
<button onClick={this.handleClick}>
Say hello
</button>
);
}
}
만약 위 문법이 마음에 들지 않는다면, experimental Class Property 를 사용해 정의할 수 있다. 즉, arrow function을 사용해 바인딩하는 것이다.
class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'Hello!'};
}
// WARNING: this syntax is experimental!
// Using an arrow here binds the method:
handleClick = () => {
alert(this.state.message);
}
render() {
return (
<button onClick={this.handleClick}>
Say hello
</button>
);
}
}
이 문법은 실험적이라는 점을 꼭 생각하고 사용해야 한다.
이와는 별개로, createReactClass()는 자동적으로 바인딩이 된다.
var SayHello = createReactClass({
getInitialState: function() {
return {message: 'Hello!'};
},
handleClick: function() {
alert(this.state.message);
},
render: function() {
return (
<button onClick={this.handleClick}>
Say hello
</button>
);
}
});
정리하자면, binding을 하기 위해선 다음과 같이 해야 한다.
- constructor와 함께 method를 바인딩한다.
- arrow function을 사용해라.
onClick={(e) => this.handleClick(e)}
- createReactClass() 를 사용해라.
ES6는 mixin을 지원하지 않는 상태로 출시되었으므로, React에선 ES6 class를 사용할 경우 이를 지원하지 않는다.
따라서, 이를 코드에 포함시키는 것을 권장하지 않는다.
만약 완전히 다른 컴포넌트가 기능적으로 비슷한 일을 할 때, createReactClass는 mixin을 사용해 이를 해결할 수 있다.