이벤트 전파
이벤트 전파(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;
제출하기 버튼을 클릭해도 이제는 더 이상 전체 페이지가 다시 로드되지 않는 것을 확인할 수 있습니다.