Skip to main content

이벤트 기초

2.5 커스텀 이벤트 디스패치

리액트 예제

사용 사례

  • 다른 컴포넌트와 이벤트를 느슨하게 결합하고 싶을때 사용하면 좋을것 같다.

JS DOM에서 window 객체와 document 객체의 차이점은?

  • window = 브라우저 창 자체
  • DOM = window의 하위 요소, 웹 페이지 DOM 을 가르킨다.

전역 커스텀 이벤트를 만들건데 둘 중 어느 객체에 연결해야해?

  • window : DOM에 상관없이 어디서든 이벤트를 처리하고 싶을때
  • DOM : DOM요소에서 이벤트가 발생하는 경우

Consumer, Producer

// Consumer.jsx
import React, { useEffect } from "react";

const Consumer = () => {
useEffect(() => {
const handleCustomEvent = (e) => {
console.log(e);
};

document.addEventListener("CUSTOM_EVENT", handleCustomEvent);

return () =>
document.removeEventListener("CUSTOM_EVENT", handleCustomEvent);
}, []);

return <div>Consumer</div>;
};

export default Consumer;
---
// Producer.jsx
import React from "react";

const Producer = () => {
const produceCustomEvent = () => {
const customEvent = new CustomEvent("CUSTOM_EVENT", {
detail: {
message: "Hello from Producer",
},
bubbles: true,
cancelable: true,
composed: true,
});
document.dispatchEvent(customEvent);
};

return (
<div>
Producer
<button onClick={produceCustomEvent}>Producer Event</button>
</div>
);
};

export default Producer;


Redux 구조 처럼 만들기

-- customEventTypes.js
export const CUSTOM_EVENT_A = 'CUSTOM_EVENT_A';

-- customEventActions.js
export const CustomEventA = (payload) => {
return { type: CUSTOM_EVENT_A, payload };
};

-- utils
export const produceCustomEvent = ({ type = '', payload = {} } = {}) => {
const customEvent = new CustomEvent(type, {
detail: payload,
bubbles: true,
cancelable: true,
composed: true
});
window.dispatchEvent(customEvent);
};


export const useCustomEventSubscriber = ({ type, onEvent }) => {
useEffect(() => {
const handleCustomEvent = e => {
onEvent(e);
};

window.addEventListener(type, handleCustomEvent);

return () => window.removeEventListener(type, handleCustomEvent);
}, [type, onEvent]);

return null;
};
usage 

-- producer
... // in event handler
produceCustomEvent(CustomEventA(payload))

-- consumer
... // in react component
useCustomEventSubscriber({
type:CUSTOM_EVENT_A,
onEvent:e =>{
const payload = e.detail.payload;
}
})