Skip to content

이벤트 핸들링 (Event Handling)

이벤트 핸들링은 사용자의 행동에 반응해 특정 동작을 실행하는 것을 의미한다.

JavaScript에서는 DOM 요소를 직접 선택해 addEventListener로 이벤트를 등록하는 반면, React에서는 JSX 안에서 onClick, onChange, onSubmit과 같은 이벤트 속성에 이벤트 핸들러 함수를 전달한다.

js
// JS
const button = document.querySelector("button");

button.addEventListener("click", () => {
  console.log("버튼 클릭");
});
jsx
// JSX
const Button = () => {
  const onClickButton = () => {
    console.log("버튼 클릭");
  };

  return <button onClick={onClickButton}>클릭</button>;
};

React 이벤트 작성 방식

jsx
// React
<button onClick={handleClick}>클릭</button>

// 잘못된 방식
<button onClick={handleClick()}>클릭</button>
  • 이벤트 이름은 camelCase 방식으로 작성
  • 이벤트 핸들러에는 함수를 직접 실행한 결과가 아니라, 실행할 함수 자체를 전달
  • handleClick()처럼 괄호를 붙이면 버튼을 클릭했을 때 실행되는 것이 아니라, 컴포넌트가 렌더링되는 순간 바로 실행된다. 클릭 이벤트가 발생하기 전에 함수가 먼저 실행되고, 그 함수의 반환값이 onClick에 전달되기 때문.

이벤트 객체

이벤트가 발생하면 React는 이벤트 핸들러 함수에 이벤트 객체를 전달한다.

jsx
const Button = () => {
  const onClickButton = (e) => {
    console.log(e);
  };

  return <button onClick={onClickButton}>클릭</button>;
};
  • 매개변수 e에는 이벤트와 관련된 정보가 담겨 있다.
  • ex. 어떤 요소에서 이벤트가 발생했는지, 이벤트 타입이 무엇인지, 기본 동작을 막을 수 있는 메서드 등이 포함된다.

합성 이벤트 (Synthetic Event)

React에서 이벤트 핸들러가 받는 이벤트 객체는 브라우저의 기본 이벤트 객체가 아니라, React가 한 번 감싼 합성 이벤트(Synthetic Event)이다.

jsx
const onClickButton = (e) => {
  console.log(e); // SyntheticBaseEvent
};

합성 이벤트는 브라우저마다 조금씩 다른 이벤트 동작을 React가 동일한 방식으로 사용할 수 있도록 통일한 이벤트 객체다.


이벤트 객체에서 자주 사용하는 속성과 메서드

e.target

이벤트가 실제로 발생한 요소를 의미한다.

jsx
const InputExample = () => {
  const onChangeInput = (e) => {
    console.log(e.target.value);
  };

  return <input onChange={onChangeInput} />;
};

input에 값을 입력하면 e.target.value를 통해 현재 입력값을 가져올 수 있다.


e.currentTarget

이벤트 핸들러가 연결된 요소를 의미한다.
e.targete.currentTarget은 비슷해 보이지만 차이가 있다.

jsx
const Button = () => {
  const onClickButton = (e) => {
    console.log("target:", e.target);
    console.log("currentTarget:", e.currentTarget);
  };

  return (
    <button onClick={onClickButton}>
      <span>클릭</span>
    </button>
  );
};

위 코드에서 span 영역을 클릭하면 다음과 같이 볼 수 있다.

jsx
e.target; // 실제 클릭된 요소: span
e.currentTarget; // 이벤트 핸들러가 연결된 요소: button

즉, target은 실제 이벤트가 발생한 요소이고, currentTarget은 이벤트 핸들러가 등록된 요소이다.


e.preventDefault()

브라우저의 기본 동작을 막을 때 사용한다.

jsx
const FormExample = () => {
  const onSubmitForm = (e) => {
    e.preventDefault();

    console.log("폼 제출");
  };

  return (
    <form onSubmit={onSubmitForm}>
      <input />
      <button type="submit">제출</button>
    </form>
  );
};

form 태그는 제출될 때 페이지를 새로고침하는 기본 동작을 가지고 있다.
React에서는 이 동작을 막고 직접 제출 로직을 처리하는 경우가 많다.


e.stopPropagation()

이벤트가 부모 요소로 전달되는 것을 막을 때 사용한다.

HTML 요소는 중첩되어 있기 때문에, 자식 요소에서 발생한 이벤트가 부모 요소까지 전달될 수 있다. 이를 이벤트 버블링이라고 한다.

jsx
const EventExample = () => {
  const onClickParent = () => {
    console.log("부모 클릭");
  };

  const onClickChild = (e) => {
    e.stopPropagation();
    console.log("자식 클릭");
  };

  return (
    <div onClick={onClickParent}>
      <button onClick={onClickChild}>버튼</button>
    </div>
  );
};
  • 위 코드에서 버튼을 클릭하면 원래는 버튼의 클릭 이벤트가 부모 div까지 전달된다.
    하지만 e.stopPropagation()을 사용했기 때문에 부모의 클릭 이벤트는 실행되지 않는다.

인자 전달하기

이벤트 핸들러에 특정 값을 함께 전달하고 싶을 때는 화살표 함수를 사용한다.

jsx
const ButtonList = () => {
  const onClickButton = (id) => {
    console.log(`${id}번 버튼 클릭`);
  };

  return (
    <>
      <button onClick={() => onClickButton(1)}>1번 버튼</button>
      <button onClick={() => onClickButton(2)}>2번 버튼</button>
    </>
  );
};
  • onClick={onClickButton(1)}처럼 바로 호출하면 안 된다.
    onClickButton(1)처럼 작성하면 클릭하기 전에 함수가 바로 실행된다. 클릭했을 때 실행되도록 하려면 화살표 함수로 감싸서 함수를 전달해야 한다.

이벤트 객체와 인자를 함께 전달하기

이벤트 객체와 추가 인자를 모두 사용하고 싶다면 다음과 같이 작성할 수 있다.

jsx
const Button = () => {
  const onClickButton = (e, name) => {
    console.log(e.target);
    console.log(`${name} 버튼 클릭`);
  };

  return <button onClick={(e) => onClickButton(e, "저장")}>저장</button>;
};
  • 이벤트 객체 e는 React가 이벤트 핸들러에 자동으로 전달해준다.
    하지만 추가 인자를 함께 전달하려면 직접 화살표 함수를 사용해 e와 원하는 값을 함께 넘겨야 한다.