react 프로젝트에 event bus 적용해보기

J·2023년 10월 9일
post-thumbnail

회사 프론트엔드 프로젝트에 event bus를 적용해보자는 피드백이 있어서
적용해보기 전에 간단한 demo 버전을 만들어서 적용해보았다.

출처 : event bus 포스팅

event bus란?

publish/subscribe 방식의 통신 패턴이다.
publisher와 subscriber는 상대방이 누구인지 알 필요 없고
단지 이벤트의 발생 여부만 알면 되어서 느슨한 결합으로 통신을 지원한다.

event bus의 구성요소

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
}
  • on : subscriber가 이벤트를 구독하고 이벤트 핸들러를 등록함
  • off : subscriber가 이벤트 구독을 취소함
  • emit : publisher가 이벤트를 버스로 보냄
  • once : subscriber가 이벤트를 한 번만 들을 수 있음

간단한 form으로 event bus 적용해보기

event bus 구현

event bus 코드는 출처 포스팅의 github 내의 event bus를 그대로 사용했음
github 링크 : event bus 코드

channel 구현

원본 포스팅에서도 channel을 따로 만들어서 사용했는데,
channel을 사용하는 이유는 event의 관심사 분리를 위해서라고 한다.

export const inputEventChannel = eventbus<{
  onInput: (text: string) => void;
  onSend: (text: string) => void;
}>();

onInput은 input tag에,
onSend는 submit 버튼을 누를 때 사용할 것이다.

event sub/unsub

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

profile
꾸준한 노력파 개발자의 이모저모

1개의 댓글

comment-user-thumbnail
2023년 10월 10일

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

답글 달기