Development/ReactJs

[React] 리액트 이벤트 핸들링 - 이벤트 핸들링 및 전파

재은초 2025. 3. 7. 21:07
반응형

이벤트 핸들링

이벤트 핸들러 추가하기

  • 이벤트 핸들러(event handler)란 사용자의 마우스 클릭이나 키보드 동작, 사용자 입력의 포커스 등과 같은 이벤트가 발생했을 때 그 처리를 담당하는 실행 함수를 가리킨다. React에서는 이러한 이벤트 핸들러를 JSX 코드 내에 작성하여 추가함으로써 해당 이벤트를 처리할 수 있다.
// 버튼을 클릭하면 간단한 경고 대화 상자를 띄우는 예제
// App.js

const App = () => {
  const handleClick = () => {
    alert("버튼을 클릭했습니다!");
  };

  return <button onClick={handleClick}>클릭하세요!</button>;
};

export default App;
  • React에서 이벤트 핸들러의 이름은 일반적으로 ‘handle’이라는 단어로 시작하여 처리하고자 하는 이벤트명을 뒤에 추가하는 방식으로 작성한다.
// React 이벤트 핸들러 이름 예시

const handleClick = () => {
  // onClick 이벤트를 처리하는 코드
}
const handleMouseEnter = () => {
  // onMouseEnter 이벤트를 처리하는 코드
}
  • HTML에서는 이벤트 프로퍼티의 이름으로 onclick, onkeydown과 같이 소문자만을 사용하지만, React에서는 다른 DOM 속성을 표기할 때처럼 카멜 표기법(camelCase)으로 작성해야 한다. 그리고 HTML에서는 큰따옴표(””)를 사용하여 문자열 형태로 이벤트 핸들러를 전달하지만, React에서는 문자열이 아닌 함수 형태의 객체를 prop으로 전달해야 한다.
// HTML
<button onclick="handleClick()"> 확인 <button>

// React
<button onClick={handleClick}"> 확인 </button>
  • 또한, JSX 코드 내에서 인라인 방식으로 이벤트 핸들러를 선언과 동시에 전달할 수도 있으며, 보다 간결하게 화살표 함수를 사용할 수도 있다.
// 일반 함수
<button onClick={function handleClick() {
  alert("버튼을 클릭했습니다!");
}}>

// 화살표 함수
<button onClick={() => {
  alert("버튼을 클릭했습니다!");
}}>
  • React에서 이벤트 핸들러는 호출하는 것이 아니라 전달되어야만 한다. 다음 코드는 이벤트 핸들러의 뒤에 실수로 소괄호(())를 붙였기 때문에 함수를 전달하는 것이 아니라 호출하는 코드가 되었다. 이렇게 이벤트 프로퍼티에 이벤트 핸들러를 호출하는 코드를 전달하면 버튼을 클릭했을 때 실행되는 것이 아니라 해당 페이지가 렌더링(rendering)될 때마다 곧바로 실행되게 된다.
// 잘못된 예제 - 해당 페이지가 렌더링될 때마다 즉시 호출됨!
<button onClick={handleClick()}> 확인 </button>

// 올바른 예제
<button onClick={handleClick}> 확인 </button>

이벤트 핸들러에서 props 참조하기

  • 이벤트 핸들러는 React 컴포넌트 내부에서 선언되기 때문에 컴포넌트의 props에 손쉽게 접근할 수 있다.
// ControlPanel.js
// 버튼을 클릭하면 message prop으로 전달된 값을 경고 대화 상자에 보여주는 예제

const ControlButton = ({ message, children }) => {
  return <button onClick={() => alert(message)}>{children}</button>;
};

const ControlPanel = () => {
  return (
    <>
      <ControlButton message="음악을 재생합니다.">▶ Play</ControlButton>
      <ControlButton message="재생을 중지합니다.">▣ Stop</ControlButton>
    </>
  );
};

export default ControlPanel;

이벤트 핸들러를 props로 전달하기

  • 부모 컴포넌트에서 자식 컴포넌트의 이벤트 핸들러를 동적으로 명시해야 할 경우가 생길 수 있다. 그럴 경우에는 부모 컴포넌트로부터 전달 받은 props를 그대로 이벤트 핸들러에 전달하면 된다.
// ControlPanel.js

// 부모 컴포넌트로부터 전달받은 props를 그대로 이벤트 핸들러에 전달
// Button 컴포넌트에서 onClick을 그대로 button의 onClick에 전달
const Button = ({ onClick, children }) => {
  return <button onClick={onClick}>{children}</button>;
};

const PlayButton = ({ musicName }) => {
  const handlePlayClick = () => {
    alert(`${musicName}을 재생합니다.`);
  };

  return <Button onClick={handlePlayClick}>▶ Play "{musicName}"</Button>;
};

const StopButton = () => {
  return <Button onClick={() => alert("재생을 중지합니다.")}>▣ Stop</Button>;
};

const ControlPanel = () => {
  return (
    <>
      <PlayButton musicName="TRUST" />
      <StopButton />
    </>
  );
};

export default ControlPanel;

 

이벤트 전파

이벤트 전파(event propagation)

  • React에서는 이벤트가 발생할 경우 이벤트가 시작된 요소로부터 상위 방향으로 이벤트가 순서대로 전파된다. 즉, React에서 이벤트 핸들러(event handler)는 모든 하위 요소에서 발생한 이벤트를 수신할 수 있는 것이다.
// ControlPanel.js
// 버튼을 클릭하면 onClick 이벤트가 발생
// 해당 <button>요소의 onClick 이벤트 핸들러가 실행
// 그리고 <button>의 상위 요소인 <div>의 onClick 이벤트 핸들러도 실행

const ControlPanel = () => {
  return (
    <div
      onClick={() => {
        alert("<div>요소를 클릭했습니다!");
      }}
    >
      <button
        onClick={() => {
          alert("Play 버튼을 클릭했습니다!");
        }}
      >
        ▶ Play
      </button>
      <button
        onClick={() => {
          alert("Stop 버튼을 클릭했습니다!");
        }}
      >
        ▣ Stop
      </button>
    </div>
  );
};

export default ControlPanel;

이벤트 전파의 중지

  • 이벤트 객체(event object)는 특정 타입의 이벤트에 대한 상세한 정보를 저장하고 있는 객체다. 이벤트 핸들러는 이러한 이벤트 객체만을 인수로 전달받을 수 있으며, 전달받은 이벤트 객체를 사용하여 이벤트의 전파를 중지할 수도 있다.
// App.js
// 버튼 클릭했을 때 이벤트 객체의 stopPropagation() 메소드를 호출하여 onClick 이벤트에 대한 이벤트 전파 중지
const Button = ({ onClick, children }) => {
  return (
    <button
      onClick={(e) => {
        e.stopPropagation();
        onClick();
      }}
    >
      {children}
    </button>
  );
};

기본 동작 방지

  • 일부 브라우저 이벤트에는 기본 동작(default behavior)이 설정되어 있다. 예를 들면, <form>요소 내부에 위치한 버튼을 클릭했을 경우 onSubmit 이벤트가 발생하고, 발생한 이벤트는 기본적으로 전체 페이지를 다시 로드하게 된다.
// App.js
// <input>요소의 입력 필드에 텍스트를 입력하고 제출하기 버튼을 클릭하면, 전체 페이지가 다시 로드됨

const App = () => {
  return (
    <form onSubmit={() => alert("제출중입니다!")}>
      <input />
      <button>제출하기</button>
    </form>
  );
};

export default App;
  • HTML에서는 이벤트 핸들러에 false 값을 전달함으로써 이러한 기본 동작이 실행되지 않도록 설정할 수 있다. 하지만 React에서는 이벤트 핸들러에 false 값을 전달하는 것이 아니라 preventDefault() 메소드를 명시적으로 호출해야만 기본 동작의 실행을 방지할 수 있다.
// App.js

const App = () => {
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        alert("제출중입니다!");
      }}
    >
      <input />
      <button>Submit</button>
    </form>
  );
};

export default App;

 

반응형