[React] event handling 하는 법

2022. 7. 12. 17:56·Framework | Library/React.js
728x90

React elements에 대한 event handling은 DOM element에 대한 event handling과 매우 유사하다.

하지만 몇 가지 차이점이 있다.

React element 이벤트 핸들링 기본

  • React 에서 events 이름은 반드시 camelCase(카멜케이스, 낙타표기)를 사용해야 한다.
  • React 에서 event handler(이벤트 핸들러)는 JSX 형태로 함수를 표기한다.
// 기존 DOM element 에서 사용하는 방법
<button onclick="activateLasers()">
  Activate Lasers
</button>

// React에서 사용하는 방법
<button onClick={activateLasers}>
  Activate Lasers
</button>

위 예제를 살펴보면, onClick과  같이 camelCase로 이벤트 이름을 설정하고, event handler의 연결은 JSX 표기인 { } 를 사용하고 있다.

 

※ React element 이벤트 핸들러 연결 시 this 객체 사용 주의 ※

다음 코드를 살펴보자

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

    // This binding is necessary to make `this` work in the callback
    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>
    );
  }
}

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

위 코드의 로직은, button에 onClick이 발생하면, Toggle 컴포넌트에 있는 handleClick 함수를 호출하도록 연결하고 있다.

여기에서 constructor에 binding 부분을 주목해보자.

constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
}

살펴 보면, this.handleClick 함수에 this를 bind 하고 있다.

여기서 this는 Toggle 컴포넌트를 뜻한다. 왜 this를 bind 해야 할까?

사실 내용은 간단하다. JSX를 사용해서, this.handleClick을 연결했을 때, JSX는 this를 bind 하지 않는다.

따라서, 핸들러 함수 내부에서 this 객체(컴포넌트 자기자신)를 사용하려면, 그 전에 미리 this를 bind 해줘야 한다.

handleClick() {
    // 여기서 this(Toggle)을 사용하려면, 반드시 this가 bind 되어 있어야 한다.!
    this.setState(prevState => ({
        isToggleOn: !prevState.isToggleOn
    }));
}

※ this를 bind하는 기본적인 방법 ※

// 1. constructor에서 method에 this을 bind 하기
constructor(props) {
    super(props);

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
}

또는 아래와 같이 this를 bind할 수도 있다.

// 2. event hanler함수를 연결할때 bind를 하기
render() {
    return (
        <button onClick={this.handleClick.bind(this)}>
            {this.state.isToggleOn ? 'ON' : 'OFF'}
        </button>
    );
}

위 2가지 방법이 가장 일반적으로 event handler 함수에 this를  bind 하는 방법이다.

react document에서는 추가적으로 2가지 방법을 더 소개하고 있다.

※ this를 bind하는 추가적인 방법 ※

  • event handler 를 정의하는 시점에 es6 문법의 array function style로 정의
class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {
    console.log('this is:', this);
  }

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

이 방법은 babel 컴파일 중 에러가 발생하는 경우도 존재한다.이 방법이 되는 이유는 es6의 () => 문법이 this를 bind 해주는 형태이기 때문이다.

  • JSX로 event handler를 연결할 때 anonymouse 형태의 arrow function을 사용하기
class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

// 이 방식은 사실 아래 코드처럼 되는 것과 같다.
let self = this;
onClick = function (e) {
    self.handleClick(e); // caller인 self (LogginButton) 컴포넌트가 this로 bind
}

이 방법은 babel 컴파일 중 에러가 발생하지 않는다. 이 방법이 되는 이유는 anonymouse로 생성된 function에서 명시적으로 this.handleClick(e)을 호출하기 때문에 this가 handler에 bind 된다.

이 방법의 단점은 component(LogginButton)이 render 될 때마다 그때마다 anonymouse 함수가 생성되는데 있다. 일반적으로 대부분의 경우에는 큰 문제 없지만, event handler가 대용량의 re-rendering이 필요한 경우에는 성능상의 문제가 발생할 수 있다.

정리

  • React 에서 event handler함수는 camelCase(낙타표기)를 사용해야 한다.
  • React 에서 event handler(이벤트 핸들러)는 JSX 형태로 함수를 표기한다.
  • React 에서 event handler 표기시 this객체 bind에 주의하여야 한다.
  • React 에서 event handler에 this객체 bind는 일반적으로 생성자(constructor)에서 하는 것을 권장한다.

'Framework | Library > React.js' 카테고리의 다른 글

[React] 이벤트 핸들러에 인자 전달하기  (0) 2022.07.12
[React] Virtual DOM(VDOM)과 Diffing 알고리즘  (0) 2022.07.12
[React] React hooks - useReducer  (0) 2022.07.12
[React] props  (0) 2022.07.11
'Framework | Library/React.js' 카테고리의 다른 글
  • [React] 이벤트 핸들러에 인자 전달하기
  • [React] Virtual DOM(VDOM)과 Diffing 알고리즘
  • [React] React hooks - useReducer
  • [React] props
arajo
arajo
  • arajo
    아라 메모장
    arajo
  • 전체
    오늘
    어제
    • 분류 전체보기 (509)
      • Language (298)
        • HTML (55)
        • CSS (11)
        • JavaScript (70)
        • TypeScript (8)
        • Python (33)
        • Java (119)
        • C (0)
        • C# (2)
      • Programming (92)
        • Programming (14)
        • Web (51)
        • Apache (1)
        • MySQL (23)
        • AWS (3)
      • Framework | Library (26)
        • Framework | Library (3)
        • Vue.js (2)
        • React.js (5)
        • React Native (4)
        • Node.js (1)
        • Ajax (1)
        • Bootstrap (8)
        • Spring (1)
        • Flutter (1)
      • etc (2)
      • 휴식 (19)
        • 책 (13)
        • 일기 (5)
        • 게임 일기 (1)
      • A (71)
        • 공부 (18)
        • 기타 (6)
        • 일 (47)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    객체
    제어문
    자바스크립트
    Java
    변수
    react
    HTML
    web
    MySQL
    CSS
    TypeScript
    타입스크립트
    event
    array
    Python
    next.js
    리액트
    JavaScript
    파이썬
    object
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
arajo
[React] event handling 하는 법
상단으로

티스토리툴바