https://www.robinwieruch.de/react-event-bubbling-capturing/
1. 개요
리액트 컴포넌트를 여러개 tree구조로 만들고 각각의 컴포넌트에다가 click 리스너를 달았다고 하자.
그리고 클릭 이벤트를 발생시켰다. 그럼 tree구조의 어떤 컴포넌트의 이벤트부터 먼저시킬까?
결론부터 말하면 캡처링과 버블링에 관해 이해를 해야한다.
이를 이해하기 위해서는 이벤트의 발생단계를 알아야 한다!
2. 이벤트의 발생단계
DOM의 이벤트 전달은 총 3단계로 구분된다.
- Capturing : 부모의 엘리먼트부터 자식 엘리먼트 방향으로 이벤트가 전달된다
- Target : 이벤트가 발생한곳, Target 지점까지 이벤트가 전달된다
- Bubbling : Target 엘리먼트에서 다시 부모 엘리먼트 방향으로 이벤트가 전달된다.
즉 위 그림을 보면 이벤트는 Window부터 Target을 향해 위아래로 쓱싹 훑는 것이다!
그리고 이벤트가 엘리먼트를 훑을때 마다 click이벤트 핸들러가 있으면 이를 실행시킨다!
3. SyntheticEvent
다음 얘기로 넘어가기 전에 한가지 개념을 습득하고 가자. 리액트의 이벤트는 DOM API의 이벤트의 Wrapper 버전이다. 즉 완전히 같지는 않다. 이 랩핑한 인스턴스를 리액트에서는 SyntheticEvent라고 한다.
4. onClick 그리고 onClickCapture
자 위 그림에서 우리는 이벤트가 어떻게 전달되는지 알았다. 이벤트가 위아래로 한바퀴 싹 훑는걸 알았는데 그럼 나는 언제 이벤트 핸들러를 발생시킬 까?
리액트는 이에대해 두가지 방법을 제시한다.
- onClick : 버블링 시점에서 이벤트를 발생시킨다.
- onClickCapture : 캡처링 시점에서 이벤트를 발생시킨다
onClick은 우리가 자주쓰니깐 잘 안다. 사실 이는 버블링시점에서 이벤트를 발생시키는 것 이였다. 그럼 우린 캡처링 시점에서는 onClickCapture를 쓰면 되는 것 이다.
버블링에 대한 예제
function App() {
const handleOuterClick = () => {
console.log('outer click');
};
const handleInnerClick = () => {
console.log('inner click');
};
return (
<div onClick={handleOuterClick}>
<div onClick={handleInnerClick}>
Click Me
</div>
</div>
);
}
결과:
inner click
outer click
캡처링에 대한 예제
function App() {
const handleOuterClick = () => {
console.log('outer click');
};
const handleInnerClick = () => {
console.log('inner click');
};
return (
<div onClickCapture={handleOuterClick}>
<div onClickCapture={handleInnerClick}>
Click Me
</div>
</div>
);
}
결과:
outer click
inner click
5. Target에서만 이벤트를 실행시키고 싶을 때!
만약 이벤트의 캡처링과 버블링 시점에서 다른 엘리먼트들의 이벤트 핸들러 호출을 막고 싶다면?
아래의 예제처럼 stopPropagation을 사용하면 된다!
아래 예제에 stopPropagation을 사용하지 않으면 버블링때문에 숫자가 2씩 올라가게 된다.
import * as React from 'react';
function App() {
const [count, setCount] = React.useState(0);
const handleCount = (event) => {
setCount((state) => state + 1);
event.stopPropagation();
};
return (
<div onClick={handleCount}>
<button type="button" onClick={handleCount}>
Count: {count}
</button>
</div>
);
}
export default App;
6. target과 currentTarget
캡처링과 버블링으로 이벤트가 호출된다고 하자. 허나 전달되는 이벤트의 실제 target과, 이벤트가 전달되는 과정에서 발생하는 이벤트의 엘리먼트들을 구분하고 싶을 때가 있다. 이는 target과 currentTarget으로 구분가능하다.
event.target
event.currentTarget
'React' 카테고리의 다른 글
부모 컴포넌트에서 자식 컴포넌트 함수 호출하기 (0) | 2022.11.17 |
---|---|
forwardRef, useImperativeHandle에 대한 이해 (0) | 2022.11.17 |
리액트에서 특정페이지 스크롤 막기 (0) | 2022.11.16 |
초 간단 Redux 사용법 (0) | 2022.11.08 |
Framer 애니메이션 배우기 (0) | 2022.11.01 |
댓글