..

Search

20) 이벤트 전파

이벤트 전파


이벤트 전파(event propagation)

React에서는 이벤트가 발생할 경우 이벤트가 시작된 요소로부터 상위 방향으로 이벤트가 순서대로 전파됩니다. 즉, React에서 이벤트 핸들러(event handler)는 모든 하위 요소에서 발생한 이벤트를 수신할 수 있는 것입니다.

 

다음 예제를 통해 버튼을 클릭했을 때 onClick 이벤트가 전파되는 방향을 확인할 수 있습니다.

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

export default ControlPanel;

위의 예제에서 버튼을 클릭하면 onClick 이벤트가 발생하고, 해당 <button>요소의 onClick 이벤트 핸들러가 실행됩니다. 그리고 <button>의 상위 요소인 <div>에도 onClick 이벤트 핸들러가 등록되어 있기 때문에 <div>의 onClick 이벤트 핸들러도 실행되게 됩니다.

 

자바스크립트 이벤트 전파 수업 복습하기 ⇒


이벤트 전파의 중지

이벤트 객체(event object)는 특정 타입의 이벤트에 대한 상세한 정보를 저장하고 있는 객체입니다.

이벤트 핸들러는 이러한 이벤트 객체만을 인수로 전달받을 수 있으며, 전달받은 이벤트 객체를 사용하여 이벤트의 전파를 중지할 수도 있습니다.

 

다음 예제는 버튼을 클릭했을 때 이벤트 객체의 stopPropagation() 메소드를 호출하여 onClick 이벤트에 대한 이벤트 전파를 중지하는 코드입니다.

예제(App.js)
const Button = ({ onClick, children }) => {
  return (
    <button
      onClick={(e) => {
        e.stopPropagation();
        onClick();
      }}
    >
      {children}
    </button>
  );
};
//...

 

이제 버튼을 클릭해도 더 이상 onClick 이벤트의 전파가 진행되지 않는 것을 확인할 수 있습니다.


기본 동작 방지

일부 브라우저 이벤트에는 기본 동작(default behavior)이 설정되어 있습니다. 예를 들면, <form>요소 내부에 위치한 버튼을 클릭했을 경우 onSubmit 이벤트가 발생하고, 발생한 이벤트는 기본적으로 전체 페이지를 다시 로드하게 됩니다.

 

다음 예제의 <input>요소의 입력 필드에 텍스트를 입력하고 제출하기 버튼을 클릭하면, 전체 페이지가 다시 로드되는 것을 확인할 수 있습니다.

예제(App.js)
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;

 

제출하기 버튼을 클릭해도 이제는 더 이상 전체 페이지가 다시 로드되지 않는 것을 확인할 수 있습니다.


연습문제