비실이의 개발 성장기

class 문법으로 react 개발 시, 이벤트 함수에 바인딩을 해주는 이유 본문

프론트엔드/react.js

class 문법으로 react 개발 시, 이벤트 함수에 바인딩을 해주는 이유

DubbingLee 2018. 12. 8. 14:19
ES6 class 문법으로 react 컴포넌트 개발 시, 이벤트핸들러 메소드를 선언하고

반드시 constructor 내부에서 바인딩을 해줘야 한다. 



만약, 이벤트핸들러 메소드에 바인드를 해주지 않으면 이벤트콜백이 발생했을 시

메소드 내부 this 는 예상과는 다른 곳을 참조하게 된다.




아래는 버튼을 누르면 handleClickIncrement 이벤트 함수가 호출되어 count 값을 1씩 증가시키는 간단한 react 컴포넌트다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Application extends React.Component {
  constructor(props) {
    super(props);
    
    this.state = {
      count: 0
    }
  }
  
  handleClickIncrement() {
    console.log('this: 'this);
    
    this.setState({
      count: ++this.state.count
    });
  }
  
  render() {
    return (
      <div>
        <p>{this.state.count}</p>
        <button onClick={this.handleClickIncrement}>+</button>
      </div>
    );
  }
}
 
React.render(<Application />document.getElementById('app'));
cs


https://codepen.io/braden-lee/pen/MZWpMv?editors=0010



위에 codepen 에 들어가 실행결과 화면의 '+' 을 눌러보면 count 값은 증가하지 않는다.


11 라인에 log 를 확인 해 보면 this 는 Application 컴포넌트가 아닌 전역 객체인 window 객체를 바라보고 있는 것을 확인 할 수 있다.


그러므로 count 변수가 정의되지 않았음을 나타내는 에러를 띄우게 된다.







이러한 현상이 발생하는 원인은 javascript 의 this 특성 때문이다.



javascript 에서 this는 함수가 호출되는 방식에 따라 참조하는 객체가 결정된다.


1. 객체의 메소드 형태로 호출되는 경우, this 는 객체 인스턴스를 참조한다.


2. 일반 함수로 호출되는 경우, this 는 현재 실행 호스트의 전역 객체를 참조한다.




그러므로 constructor 에서 이벤트핸들러 메소드에 this(컴포넌트 인스턴스) 를 바인딩 해주어


이벤트콜백 발생 시, 컴포넌트 참조가 가능하도록 해줘야 한다.


1
2
3
4
5
6
7
8
9
  constructor(props) {
    super(props);
    
    this.state = {
      count: 0
    }
    
    this.handleClickIncrement = this.handleClickIncrement.bind(this);
  }
cs






매번 constructor 에 bind 해주는게 번거롭다면, ES6 arrow function 을 사용하면 된다.


arrow function 은 일반적인 함수와 다르게 실행컨텍스트에서 this 를 생성하지 않는다.




1
2
3
4
5
6
7
  handleClickIncrement = () => {
    console.log('handleClickIncrement: 'this);
    
    this.setState({
      count: ++this.state.count
    });
  }
cs







참고: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/%EC%95%A0%EB%A1%9C%EC%9A%B0_%ED%8E%91%EC%85%98


0 Comments
댓글쓰기 폼