(JSX) 메서드 내에서 this를 올바르게 참조

React.Component 의 메소드를 사용할 때 this 가 올바르게 참조할 수 없는 것이 있었다. 그 원인과 대처법을 적는다. 움직일 수 있는 코드는 여기 .

문제


Click Me! 라는 문자열을 클릭했을 때 Thanks 와 문자열이 전환되는 컴퍼넌트를 구현하고 싶다.


여기서 다음과 같은 코드로 하면, 클릭해도 문자가 전환되지 않는다.
class Clickable extends React.Component {
  constructor(props) {
    super(props);
    this.state = { msg: "Click Me!"};
  };
  render () {
     return <h1 onClick={this.handleClick}>{ this.state.msg }</h1>;
  };
  handleClick () { this.setState({ msg: "Thanks!"}); };
}

ReactDOM.render(
  <Clickable/>,
  document.getElementById('mount')
);

원인은 메소드 handleClick 를 정의했을 때에, this 의 스코프가 메소드내의 것에 대신해 버려, 클래스내의 스코프의 this 를 참조할 수 없기 때문이다.

올바르게 동작시키기 위한 대처법을 아래에 적는다.

대처법 ① : 생성자로 묶는다



최초의 대처법은 클래스의 생성자내에서 클래스의 스코프로의 this 를 메소드에 속박시키는 방법이다.
class Clickable extends React.Component {
  constructor(props) {
    super(props);
    this.state = { msg: "Click Me!"};
    // 対処法①  コンストラクタ内でhandleClickを束縛する
    this.handleClick = this.handleClick.bind(this);
  };
  ...
}

이 방법은 효과적이지만, 바인딩은 생성자 내에서 수행되어야하므로 생성자를 생략 할 수 없다는 단점이 있습니다.

조치 ②: 클로저 사용



두 번째 해결책은 메소드 호출시 클로저를 사용하는 것입니다. render가 실행되었을 때, 클로저에 의해 클래스의 this가 속박되기 (위해)때문에, 메소드내에서 올바르게 참조를 실시할 수가 있게 된다.
 render () {
     return <h1 onClick={() => this.handleClick()}>{ this.state.msg }</h1>;
  };

이 작성 방법은 생성자 내에서 바인딩 할 필요가 없으므로 생성자가 필요하지 않은 경우 생략 할 수 있습니다.

대처방법③: 애로우 함수 사용



마지막 해결책은 메소드 handlwClick의 정의에 화살표 함수 표기법을 사용하는 것입니다. 애로우 함수는 변수의 리스스코프를 실시하지 않기 때문에, 원래의 this 를 메소드 내부에서 그대로 참조할 수가 있다. JavaScript에서는 함수는 1급의 객체이기 때문에, 화살 함수를 클래스의 멤버 변수로서 등록하고 있는 형태가 되고 있다.
handleClick = () =>  { this.setState({ msg: "Thanks!"}); };

이 작성 방법으로도 생성자 내에서 바인딩 할 필요가 없으므로 코드가 짧아집니다.

요약



메소드내에서 클래스의 this 를 참조하는 방법을 3개 소개했다.
아무래도 JS의 스코프는 안쪽이 깊다고 할까 버릇이 있다. .

좋은 웹페이지 즐겨찾기