React의 Synthetic Event란?
Synthetic Event(합성 이벤트)는 React가 브라우저의 기본 이벤트를 감싸서 제공하는 래퍼(wrapper) 객체입니다.
즉, 브라우저 이벤트를 추상화한 React만의 이벤트 시스템입니다.
React에서 이벤트 핸들러를 사용할 때 onClick
, onChange
같은 속성을 JSX에서 작성하면, 내부적으로 Synthetic Event가 생성되어 브라우저의 native event를 감싸게 됩니다.
1. Synthetic Event가 필요한 이유
✅ 브라우저 간 호환성 유지
- React는 모든 이벤트를 자체적으로 관리하므로, 브라우저마다 이벤트 동작이 다르게 구현되는 문제를 해결할 수 있습니다.
✅ 성능 최적화
- 이벤트 리스너를 개별 DOM 요소에 붙이는 것이 아니라, 이벤트 위임(Event Delegation)을 활용하여 루트(root) 요소에서 한 번만 관리하여 성능을 향상시킵니다.
✅ 일관된 이벤트 인터페이스 제공
- 브라우저마다 다르게 동작하는 native event를 React에서 일관되게 처리할 수 있도록 통일된 API를 제공합니다.
2. Synthetic Event 사용 예제
import React from "react";
function App() {
const handleClick = (event) => {
console.log(event); // SyntheticBaseEvent 객체 출력
console.log(event.nativeEvent); // 브라우저의 native event 객체 출력
console.log(event.target); // 클릭된 요소
console.log(event.currentTarget); // 이벤트 핸들러가 부착된 요소
};
return <button onClick={handleClick}>Click Me</button>;
}
export default App;
event
는 Synthetic Event 객체이며,event.nativeEvent
를 통해 원래 브라우저 이벤트 객체에 접근할 수 있습니다.event.target
: 이벤트가 발생한 실제 요소.event.currentTarget
: 이벤트 핸들러가 부착된 요소.
3. Synthetic Event의 특징
1) 이벤트 풀링(Event Pooling)
Synthetic Event는 성능 최적화를 위해 이벤트 객체를 재사용(Pooling)합니다.
즉, 이벤트가 끝나면 초기화되어 속성 값을 더 이상 읽을 수 없습니다.
예제: 이벤트 객체가 초기화되는 경우
function App() {
const handleClick = (event) => {
console.log(event.type); // "click"
setTimeout(() => {
console.log(event.type); // 여기서는 이미 초기화되어 "null"이 됨
}, 1000);
};
return <button onClick={handleClick}>Click</button>;
}
setTimeout
내에서event.type
을 출력하려고 하면 "null"이 되어버립니다.- 이는 Synthetic Event가 재사용되면서 초기화되었기 때문입니다.
해결 방법
React에서는 이벤트를 비동기적으로 사용할 때, event.persist() 메서드를 호출하여 이벤트 객체를 유지할 수 있습니다.
function App() {
const handleClick = (event) => {
event.persist(); // 이벤트 풀링을 방지하여 이벤트 객체 유지
setTimeout(() => {
console.log(event.type); // "click"
}, 1000);
};
return <button onClick={handleClick}>Click</button>;
}
event.persist()
를 호출하면, 해당 이벤트 객체가 풀링되지 않고 메모리에 유지됩니다.
2) 이벤트 위임(Event Delegation)
React의 Synthetic Event는 이벤트를 개별 DOM 요소가 아닌, 최상위(root) 요소에서 한 번만 관리하는 방식으로 동작합니다.
이 방식은 DOM 요소가 많아질 때 메모리 사용량을 줄이고 성능을 향상시키는 효과가 있습니다.
예제: React의 이벤트 위임
function List() {
const handleClick = (event) => {
console.log("Clicked:", event.target.innerText);
};
return (
<ul onClick={handleClick}>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
);
}
ul
요소에onClick
이벤트를 추가했지만, 개별li
요소를 클릭해도 이벤트가 정상적으로 실행됨.- React는 모든 이벤트를
document
또는root
에서 한 번만 관리하는 방식으로 이벤트 위임을 구현.
3) Native Event와의 차이점
Synthetic Event | Native Event | |
---|---|---|
관리 주체 | React에서 감싸서 제공 | 브라우저가 직접 제공 |
이벤트 풀링 | 기본적으로 활성화됨 (event.persist() 필요) |
풀링 없음 |
이벤트 위임 | 자동으로 최상위에서 관리 | 직접 구현 필요 |
호환성 | 브라우저 간 일관된 동작 제공 | 브라우저마다 차이 가능 |
4. Synthetic Event가 아닌 Native Event를 써야 하는 경우
Synthetic Event는 성능 최적화를 위해 설계되었지만, 특정한 상황에서는 브라우저의 Native Event를 직접 사용하는 것이 필요할 수도 있습니다.
1) useEffect
에서 addEventListener
를 사용할 때
useEffect(() => {
const handleScroll = (event) => {
console.log("스크롤 중", event);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
- React의 Synthetic Event는 DOM 요소에서 발생하는 이벤트에만 적용되므로,
window
나document
이벤트에는 적용되지 않습니다. - 이 경우,
addEventListener
를 사용하여 Native Event 리스너를 등록해야 합니다.
2) 이벤트 성능을 극대화해야 할 때
Synthetic Event는 React 내부에서 여러 최적화가 이루어지지만,
매우 빠른 응답 속도가 필요한 경우 (예: 마우스 드래그, 고속 키 입력 감지 등)
Native Event를 직접 사용하는 것이 성능적으로 유리할 수도 있습니다.
document.addEventListener("mousemove", (event) => {
console.log(event.clientX, event.clientY);
});
5. 결론
✅ Synthetic Event의 핵심 요약
- React가 브라우저 이벤트를 감싸서 제공하는 래퍼 객체
- 브라우저 간 이벤트 동작을 통일하고, 성능 최적화를 위해 활용
- 이벤트 풀링(Event Pooling)이 적용됨 →
event.persist()
를 호출하면 유지 가능 - 이벤트 위임(Event Delegation) 방식으로 동작하여 메모리 효율이 높음
- 특정 경우 (예:
window
이벤트, 성능 극대화 필요)에는 Native Event를 직접 사용하는 것이 유리
'TIL' 카테고리의 다른 글
[250213 TIL] TBD vs Github Flow(개념정리) (0) | 2025.02.13 |
---|---|
[250212 TIL] 애자일 방법론(개념정리) (0) | 2025.02.13 |
[250207 TIL] 제어 역전, 의존성 주입 (1) | 2025.02.07 |
[250205 TIL] 냄새나는 코드? (0) | 2025.02.05 |
[250131 TIL] Composition Event (0) | 2025.01.31 |