
회사 프론트엔드 프로젝트에 event bus를 적용해보자는 피드백이 있어서
적용해보기 전에 간단한 demo 버전을 만들어서 적용해보았다.
출처 : event bus 포스팅
publish/subscribe 방식의 통신 패턴이다.
publisher와 subscriber는 상대방이 누구인지 알 필요 없고
단지 이벤트의 발생 여부만 알면 되어서 느슨한 결합으로 통신을 지원한다.
interface EventBus {
on(key: string, handler: EventHandler): () => void
off(key: string, handler: EventHandler): void
emit(key: string, ...payload: Parameters<EventHandler>): void
once(key: string, handler: EventHandler): void
}
event bus 코드는 출처 포스팅의 github 내의 event bus를 그대로 사용했음
github 링크 : event bus 코드
원본 포스팅에서도 channel을 따로 만들어서 사용했는데,
channel을 사용하는 이유는 event의 관심사 분리를 위해서라고 한다.
export const inputEventChannel = eventbus<{
onInput: (text: string) => void;
onSend: (text: string) => void;
}>();
onInput은 input tag에,
onSend는 submit 버튼을 누를 때 사용할 것이다.
const Page = ()=>{
//랜더링 관련 코드는 생략
useEffect(() => {
//on 함수는 off를 반환한다
const unSubscribeOnInput = inputEventChannel.on(
"onInput", //event name
(text: string) => { //event handler
console.log(text);
}
);
const unSubscribeOnSend = inputEventChannel.on("onSend", (text: string) => {
const msg = `text send : ${text}`;
alert(msg);
});
//unmount시 unsubscribe
return () => {
unSubscribeOnInput();
unSubscribeOnSend();
};
}, []);
return //...
}
onInput 이벤트에는 console.log에 이벤트 버스를 통해 전달받은 input text를 출력하는 핸들러를 등록하고
onSend 이벤트에는 전달받은 text를 alert에 출력하는 핸들러를 등록한다.
const Page = () => {
const [text, setText] = useState<string>("");
//event 등록 코드는 생략
return (
<>
<form>
<input
type="text"
placeholder="text를 입력하세요"
onChange={(e) => {
const text = e.target.value;
//이벤트 전달
inputEventChannel.emit("onInput", text);
setText(text);
}}
/>
<button
type="submit"
//이벤트 전달
onClick={() => inputEventChannel.emit("onSend", text)}
>
전송
</button>
</form>
</>
);
}

onInput event

onSend event

이것이 이벤트 버스였군요!
알기 쉽게 정리가 잘 되어서 이해하기 편했습니다!
이 코드를 우리 프로젝트에도 적용하여 동작될 것을 생각하니 기대되네요 매우 유용할 것 같습니다
좋은 포스팅으로 오늘도 한 수 배우고 갑니다!