본문 바로가기
IT/스터디

이벤트 핸들링

by 봉즙 2020. 1. 23.

 

DOM 엘리먼트를 처리하는 것과 유사하다.

<button onclick="activateLasers()">
  Activate Lasers
</button>

HTML

<button onClick={activateLasers}>
  Activate Lasers
</button>

React

카멜케이스를 사용하며 리엑트에서는 false를 반환하더라도 기본동작을 방지 할 수 없어 preventDefault를 명시적으로 호출해야한다.

<a href="#" onclick="console.log('The link was clicked.'); return false">
  Click me
</a>

HTML

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

React

e는 합성이벤트이기에 브라우저에 대한 호환성에 고려할 필요가 없다.

 

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

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

    // 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

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

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

 

JSX에서는 콜백 안의 this에 대해서 주의해야 한다. javascript에서 클래스 메서드는 기본적으로 바인딩 되어있지 않다. this.handleClick을 바인딩하지 않고 onClick에 전달하였다면, 함수가 실제 호출될 때 this는 undefined가 된다. 일반적으로 onClick={this.handleClick}과 같이 뒤에 ()를 사용하지 않고 메서드를 참조할 경우, 해당 메서드를 바인딩 해야 한다.

bind를 호출하는 것이 불편한 경우엔 public 필드 클래스 문법을 사용한다면 클래스 필드를 사용하여 콜백을 올바르게 바인딩 할 수 있다.

 

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

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

 

CreateReactApp에서는 기본적으로 이 문법이 설정되어있으며 필드 클래스 문법을 사용하지 않는 경우 콜백에 화살표 함수를 사용하는 방법도 있다.

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

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

 

이 문법의 문제점은 LogginButton이 렌더링 될때 마다 다른 콜백이 생성된다는 점이다. 대부분은 문제가 되지 않으나 콜백이 하위 컴포넌트에 props로 전달되고자 한다면 그 컴포넌트들은 추가로 다시 렌더링을 할 수도 있다. 이러한 문제를 피하기 위해 생성자 안에서 바인딩하거나 클래스 문법을 사용하는 것이 권장된다.

 

핸들러에 인자 전달하기

루프 내부에서는 이벤트 핸들러에 추가적인 매개변수를 전달하는 것이 일반적이다.

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

두줄은 동일하며 화살표 함수와 Function.proptype.bind를 사용한다.

두 경우 모두 React이벤트를 나타내는 e인자가 ID뒤에 두번째 인자로 전달된다. 화살표 함수를 사용하면 명시적으로 인자를 전달해야 하지만 bind를 사용할 경우 인자가 자동적으로 전달된다.

'IT > 스터디' 카테고리의 다른 글

Hook  (0) 2020.02.04
list와 key  (0) 2020.01.30
Ref  (0) 2020.01.29
클래스형 컴포넌트, state, props  (0) 2020.01.22
JSX  (0) 2020.01.21

댓글