React 이벤트 처리

YEZI🎐·2022년 6월 27일
0

React

목록 보기
15/46

이벤트 처리하기

React 엘리먼트에서 이벤트를 처리하는 방식은 DOM 엘리먼트에서 이벤트를 처리하는 방식과 매우 유사하다. 몇 가지 문법 차이는 다음과 같다.

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

// REACT : onclick → onClick, ()를 없애고 {}로 감싸기
<button onClick={activateLasers}>
  Activate Lasers
</button>

함수 컴포넌트

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

// HTML
<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>

// REACT
function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

클래스 컴포넌트

JavaScript에서 클래스 메서드는 기본적으로 바인딩되어 있지 않다.
this.handleClick을 바인딩하지 않고 onClick에 전달하였다면, 함수가 실제 호출될 때 this는 undefined가 된다.
때문에 JSX 콜백 안에서 this의 의미에 대해 주의해야 한다.

import React from 'react';

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

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

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

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

export default Toggle;

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

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

profile
까먹지마도토도토잠보🐘

0개의 댓글