[React] 클래스 컴포넌트에서의 이벤트처리

youngseo·2022년 7월 27일
0

REACT

목록 보기
19/52
post-thumbnail

클래스 컴포넌트에서의 이벤트처리

리액트공식문서

ES6 클래스를 사용하여 컴포넌트를 정의할 때, 일반적인 패턴은 이벤트 핸들러를 클래스의 메서드로 만드는 것입니다.

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

  }
  //클래스의 매서드
  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

작성된 예제로는 버튼을 클릭하면 isTogleOn이 false로 변할 것으로 예측이 됩니다. 하지만 실제로 실행을 해보면 실행되지 않고 아래와 같은 에러가 출력되는 것을 확인할 수 있습니다.

setState가 실행될 때 this가 undefined이라고 이야기를 하고 있습니다. 한번 console.log를 실행해 확인해보도록 하겠습니다.

handleClick() {
  console.log('handleClick', this)
  this.setState(prevState => ({
    isToggleOn: !prevState.isToggleOn
  }));
}

componentDidMount() {
  console.log('componentDidMount', this)
}

render() { //render()을 붙여줘야지만 렌더가 됩니다.
  console.log('render', this)
  return (
    <button onClick={this.handleClick}>
    {this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);

render에서도 componentDidMount에서도 this는 Toggle컴포넌트를 잘 가르키고 있지만, 버튼을 클릭하면 undefined가 출력되는 것을 확인할 수 있습니다.

JavaScript에서 this는 함수를 어떻게 호출되느냐에 따라서 참조가 달라지게 됩니다. 현재는 콜백안에서의 this 사용하고 있기 때문에 다른 클래스의 this를 참조하지 못합니다.

따라서 contructor안에서 this.handleClick = this.handleClick.bind(this);를 통해 this를 바인딩 시켜줘야합니다.

bind 호출 없이 문제를 해결하는 방법

1. 퍼블릭 클래스 필드 문법 사용

class LoggingButton extends React.Component {
  // 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
  // 주의: 이 문법은 *실험적인* 문법입니다.
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

2. 화살표함수 사용

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
    return (
      <button onClick={() => this.handleClick()}>
        Click me
      </button>
    );
  }
}

하지만 화살표함수의 경우 렌더링될 떄마다 다른 콜백이 생성되기 때문에 클래스 컴포넌트에서 사용을 지양하고 있습니다.

따라서 생성자 안에서 바인딩하거나 클래스 필드 문법을 사용하는 것을 권장합니다.

0개의 댓글

관련 채용 정보