
React.js ES6: 모든 메소드에 ‘this’ 바인딩을 피하세요
React.js를 다루면서 일반 ES5에서는 모든 컴포넌트 클래스의 메소드에 ‘this’를 바인딩해야 제대로 작동한다는 점을 알 수 있었을 것입니다. 그러나 이제 ES6와 그의 새로운 멋진 기능들을 탐구하기 시작했으므로 이 반복적이고 번거로운 바인딩 프로세스를 피할 방법을 찾고 있습니다. 이 블로그 포스트에서는 이러한 과정을 단순화하고 코드를 더 간결하게 만드는 몇 가지 기술을 탐구하겠습니다.
1. 클래스 필드
하나의 방법은 클래스 필드를 사용하는 것입니다. 클래스 필드를 사용하면 생성자 외부에서 바인딩을 수행할 수 있습니다. 다음은 예시입니다:
class Foo extends React.Component {
handleBar = () => {
console.log('멋져');
};
handleFoo = () => {
console.log('멋지다');
};
render() {
return (
<div
onClick={this.handleBar}
onMouseOver={this.handleFoo}
/>
);
}
}
클래스 필드는 여전히 실험적인 기능으로 간주되지만 Babel의 클래스 속성 변환을 사용하여 활성화할 수 있습니다. 완전히 지원되기 전까지는 메소드를 수동으로 바인딩하거나 ES7을 기다려야 할 수도 있습니다.
2. 데코레이터
다른 대안은 데코레이터를 사용하는 것입니다. 프로토타입에 getter를 선언하고 인스턴스에 처음 접근할 때 해당 함수의 바인딩된 버전을 가진 속성을 정의합니다. 다음은 ‘class-bind’ 라이브러리를 사용한 예시입니다:
import { bound } from 'class-bind';
class App {
constructor(){
this.foo = 'bar';
}
@bound
returnsFoo(){
return this.foo;
}
render(){
var returnsFoo = this.returnsFoo;
return (
<div>
{returnsFoo()} === 'bar'
</div>
);
}
}
만약 데코레이터가 여전히 너무 불안정하다고 생각된다면, ‘class-bind’ 라이브러리에서 제공하는 ‘bind’나 ‘bindAll’ 메소드를 사용하여 메소드를 수동으로 바인딩할 수 있습니다.
3. 생성자 메소드에서 바인딩하기
더 수동적인 접근을 선호한다면, 모든 바인딩 작업을 별도의 메소드 내에서 정리할 수 있습니다. 다음은 예시입니다:
class MyClass {
constructor() {
this.bindMethods([
'updateLocationFields',
'render',
'loadCities',
]);
}
bindMethods(methods) {
methods.forEach((item) => {
this[item] = this[item].bind(this);
});
}
// 나머지 클래스 메소드들
}
4. 상속과 부모 컨텍스트
OOP 상속을 모방하고자 한다면, 부모 컨텍스트를 자식 컴포넌트에 전달할 수 있습니다. 이렇게 하면 명시적인 바인딩 없이도 부모의 메소드에 접근할 수 있습니다. 다음은 예시입니다:
class Parent extends React.Component {
state = { happy: false }
changeState(happy) {
this.setState({ happy });
}
render() {
return (
<Child parent={this} />
);
}
}
class Child extends React.Component {
// ...
this.props.parent.changeState(true);
}
결론
React.js 컴포넌트 클래스의 모든 메소드에 ‘this’를 바인딩하는 것은 지루해지고 코드가 덜 간결해질 수 있습니다. 그러나 위에서 언급한 기술을 사용하면 반복적인 바인딩을 피하고 코드를 더 읽기 쉽고 유지 보수하기 좋게 만들 수 있습니다. 클래스 필드, 데코레이터, 수동 바인딩 또는 상속 중 어떤 방법을 선택하든 프로젝트와 개발 스타일에 가장 적합한 방법을 찾아 React.js를 ES6에서 훨씬 향상시킬 수 있습니다.