Skip to content

리액트에서 이벤트 바인딩 방법들 💻 #14

@seungyeub

Description

@seungyeub

리액트에서의 바인딩(binding) 방법들

기존의 react에서의 React.createClass() 메소드를 사용하여 컴포넌트를 생성하면 이 메소드가 자동으로 mixin 과 autobinding을 다뤄주어 바인딩을 할 필요가 없었다.

그런데 최신 JS의 객체 지향성 클래스라는 기능을 가지게 되어 리액트도 이를 지원하게 되어 조금 더 바닐라 자바스크립트와 가깝게 되었고, 그래서 최근 리액트 프로젝트들은 컴포넌트를 es6 class를 사용하는 추세다.

다음과 같이 JS object에 달린 메소드의 this는 그 메소드가 포함된 object를 가르키게 된다.

var obj = {  
  prop: 'Hello',
  sayHello: function() {
    console.log( this.prop );
  }
};

obj.sayHello(); // Logs "Hello"

하지만 여기서 sayHello() 의 호출을 다른 방식으로 해보면 다음과 같이 undefined가 출력된다.

var reference = obj.sayHello;  

reference(); // logs "undefined"

그 이유는 바로 reference를 sayHello****에 저장할때 obj 와의 관계를 상실하기 때문, 여기에서는 메소드로써가 아니라 함수로써 호출하는 것이다.

그럼 위의 문제를 어떻게 해결해야 할까? 먼저 코드를 살펴보자.

var obj = {  
  prop: 'Hello',
  sayHello: function() {
    console.log(this.prop);
  }
};

var newFunction = obj.sayHello.bind(obj);  
newFunction(); // logs "Hello"

bind() 를 통해 새로운 함수 newFunction 의 this 가 언제나 obj 임을 가르키게 된다. 여기서 newFunction 을 호출할 때 이 함수의 this 는 bind의 첫 인자가 되는 것.

리액트에서는 위의 바인딩이 적용될 때가 꽤 자주 있다. 하지만 언제나 바인딩을 해야할 필요는 없고 다음과 같이 오직 메소드를 다른 메소드에서 사용할 때만 바인딩하면 된다.

class Home extends React.Component {

  update() {
    this.setState({
      newStuff: true
    });
  }

	render() <div onClick={ this.update } />;

}

여기서 render() 메소드가 update를 부를 때 여기서는 메소드를 호출한 것이 아니라 함수를 호출한것이다. 즉, this 가 무엇을 가리키는지 정확히 정의되지 않았기 때문에 바인딩을 통해 관계를 설정해줘야 한다.

리액트에서는 아래와 같은 방법들로 바인딩할 수 있습니다.

방법 1: render() 안에 바인딩

render() <div onClick={ this.update.bind( this ) } />;

방법2: constructor() 안에 바인딩

class Home extends React.Component {

	constructor() {
		super()
		this.update = this.update.bind(this);
	}
	...
}

방법3: 오토바인딩 데코레이터 사용

import autobind from 'autobind-decorator'

class Home extends React.Component {  
@autobind
update() {
	...
}

방법4: 그냥 createClass() 쓰기


참고 : https://blog.andrewray.me/react-es6-autobinding-and-createclass/

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions