[React]-이벤트 처리하기

2020. 8. 18. 00:57개발/React

아래 글은 React Document 를 바탕으로 만들어 졌다.

이벤트 처리하기

React 엘리먼트에서 이벤트를 처리하는 방식은 DOM 엘리먼트에서 이벤트를 처리하는 방식과 매우 유사하다.

문법 차이는 아래와 같다.

  • React의 이벤트는 소문자 대신 camelCase 를 사용한다.
  • JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달한다.
// normal DOM
<button onclick="activateLasers()">
  Activate Lasers
</button>

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

React 에서는 false를 반환해도 기본 동작을 방지할 수 없다. 반드시 preventDefault를 명시적으로 호출해야 한다.

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


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

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

여기서 e는 합성 이벤트 이다. React는 W3C 명세에 따라 합성 이벤트를 정의하기 때문에 브라우저 호환성에 대해 걱정할 필요가 없다.

React에서는 DOM 엘리먼트가 생성된 후 리스너를 추가하기 위해 addEventListener를 호출할 필요가 없다. 대신 엘리먼트가 처음 렌더링 될 때 리스너를 제공하면 된다.

ES6 클래스를 사용하여 컴포넌트를 정의할 때, 일반적인 패턴은 이벤트 핸들러를 클래스의 메서드로 만드는 것이다. 예를 들어, 다음 Toggle 컴포넌트는 사용자가 “ON”과 “OFF” 상태를 토글 할 수 있는 버튼을 렌더링한다.

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의 의미에 대해 주의해야 한다. 이는 React만의 특수한 동작이 아닌 javaScript에서 함수가 작동하는 방식의 일부이다. bind에 대한 내용은 여기 를 참고해 공부했다.

  • 간단히 정리하자면 function.bind(obj) 으로 선언되는 내용은 function 내부에서 this를 호출 하게 되면 매개변수로 넘겨준 objthis 가 된다. 예를들어 function 내부에서 this.name 을 호출하는건 함수 바깥에서 obj.name을 호출하는 것과 동일하다는 의미 이다. (obj.function() 으로도 사용할 수 있다. 암시적 바인딩, 명시적 바인딩의 우선 순위는 위 글을 참조하자)

일반적으로 onClick={this.handleClick} 과 같이 뒤에 ()를 사용하지 않고 메서드를 참조할 경우, 해당 메서드를 바인딩 해야 한다.

만약 bind를 호출하는 것이 불편하다면, 두 가지 해결 방법이 있다.

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

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

Create React App에서는 이 문법이 기본적으로 설정되어 있다.


이벤트 핸들러에 인자 전달하기

루프 내부에서는 이벤트 핸들러에 추가적인 매개변수를 전달하는 것이 일반적이다. 예를들어 id가 행의 ID 일 경우 다음 코드가 모두 동작한다.

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

위 두 줄은 동등하며 각각 화살표 함수Function.prototype.bind를 사용한다.

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

'개발 > React' 카테고리의 다른 글

[React]-리스트와 Key  (0) 2020.08.18
[React]-조건부 렌더링  (0) 2020.08.18
[React]-Component와 Props  (0) 2020.08.18
[React] - 엘리먼트 렌더링  (0) 2020.08.17
[React] - JSX  (0) 2020.08.17