React Event Handling

nara_lee·2025년 2월 25일
1
post-thumbnail

Table of Contents
1. 리액트의 이벤트 시스템
2. 예제로 이벤트 핸들링 익히기
3. 함수 컴포넌트로 구현해 보기
4. 정리

1. 리액트의 이벤트 시스템

이벤트 사용할 때 주의 사항

1. 이벤트 이름은 카멜케이스로 (e.g. onekeyup => OneKeyUp)

2. 이벤트에 실행할 자바스크립트 코드를 pass하는 것이 아니라, 함수 형태의 값을 전달한다

3. DOM 요소에만 이벤트 설정 가능

즉 div, button, input, form, span 등의 요소에는 이벤트를 설정할 수 있지만, 우리가 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다.

<MyComponent onClick={doSomething}/>

예를 들어 다음과 같이 MyComponent에 onClick 값을 설정한다면 MyComponent를 클릭할 때 doSomething 함수를 실행하는 것이 아니라, 그냥 이름이 onClick인 props를 MyComponent에게 전달해 줄 뿐이다.
따라서 컴포넌트에 자체적으로 이벤트를 설정할 수는 없다. 하지만 전달받은 props를 컴포넌트 내부의 DOM 이벤트로 설정할 수는 있다.

<div onClick={this.props.onClick}>
  {/*(...)*/}
</div>

2. 예제로 이벤트 핸들링 익히기

import { Component } from "react";

class EventPractice extends Component {
    render() {
        return (
            <div>
                <h1>이벤트 연습</h1>
                <input
                    type="text"
                    name="message"
                    placeholder="아무거나 입력해 보세요"
                    onChange={(e) => {
                        console.log(e);
                    }}
                />
            </div>
        );
    }
}

위 스크린 샷에서 볼 수 있듯 event listener는 event 객체를 전달함


syntheticEvent 란?

Blogger explains:
syntheticEvent vs. native(browser)event 을 따로 쓰면 하나의 bubbling을 막으면 나머지 하나는 자동으로 막히지 않는다. 왠만하면 하나로 통일된 syntheticEvent만 쓰도록 하자.

React Official Says:

syntheticEvent conforms to the same standard as the underlying DOM events, but fixes some browser inconsistencies.


binding의 필요성

함수가 호출될 때 this는 호출부에 따라 결정되므로, 클래스의 임의 메서드가 특정 HTML 요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계가 끊어져 버린다. 이 때문에 임의 메서드가 이벤트로 등록되어도 this가 컴포넌트 자신으로 제대로 가리키기 위해서는 메서드를 this와 bind하는 작업이 필요하다.
아래 예시에서는 constructor에서 이 작업을 해주고 있다.

constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
  this.handleClick = this.handleClick.bind(this);
}
(...)
render() {
    return (
      <div>
        <h1>이벤트 연습</h1>
        <input
          type="text"
          name="message"
          placeholder="아무거나 입력 ㄱ"
          value={this.state.message}
          onChange={this.handleChange}
          //만약 위에서 bind를 안했다면 this가 undefined를 가리키게 됨.
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }

하지만 새 method를 만들 때마다 constructor를 수정해줘야 하기 때문에 binding 작업이 귀찮다...
바벨의 transform-class-properties 문법을 사용하여 화살표 함수 형태로 메서드를 정의해 binding 작업을 간소화 해보자.

이랬던 걸

 handleChange(e) {
    this.setState({
      message: e.target.value,
    });
  }
  handleClick() {
    alert(this.state.message);
    this.setState({
      message: "",
    });
  }

이렇게 바꾸면 ⬇︎⬇︎⬇︎ constructor 를 아예 안써도 된다.

  handleChange= (e) => {
    this.setState({
      message: e.target.value,
    });
  }
  handleClic= () => {
    alert(this.state.message);
    this.setState({
      message: "",
    });
  }

객체 안에서 key를 []로 감싸면 그안에 넣은 레퍼런스가 가르키는 실제 값이 key 값으로 사용된다. 길벗 p135

3. 함수 컴포넌트로 구현해 보기

e.target.name 값을 활용하려면, useState을 쓸 때 인풋 값들이 들어있는 form 객체를 사용하자


본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리] 한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.

#한컴AI아카데미 #AI개발자 #AI개발자교육 #한글과컴퓨터 #한국생산성본부 #스나이퍼팩토리 #부트캠프 #AI전문가양성 #개발자교육 #개발자취업

3개의 댓글

comment-user-thumbnail
2025년 2월 25일

답글 달기
comment-user-thumbnail
2025년 2월 26일

좋은 내용이네요. 잘 보고 갑니다.

답글 달기