React.js의 게시자 구독자 패턴

14251 단어 reactjavascript
지난 주에 Publisher subscriber(Pub-Sub) 패턴이라는 패턴을 배우고 이를 리액트로 구현해 보았습니다. 이는 React의 컨텍스트 API나 Redux와 같은 타사 라이브러리를 사용하여 쉽게 수행할 수 있지만 저는 다른 접근 방식을 취했습니다.

tl;dr: NOTE: This code is not production ready. Complete working app can be found here



Pub/Sub 패턴이란 무엇입니까?



위키피디아에 따르면

Pub-Sub is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers, but instead categorize published messages into classes without knowledge of which subscribers, if any, there may be. Similarly, subscribers express interest in one or more classes and only receive messages that are of interest, without knowledge of which publishers, if any, there are.



간단히 말해서 게시자와 구독자는 서로를 인식하지 못합니다. 그들 사이의 모든 통신은 게시자에서 내보내고 구독자에게 알리는 이벤트를 통해 이루어집니다. 아래와 같이

Pubsub 패턴 소스msd blog


이것을 React에서 구현하기



Pub-Sub 패턴을 사용하여 단 두 개의 이벤트(on 및 emit)로 수행할 수 있는 가장 단순화된 방식으로 반응하려고 했습니다.

이 예에서는 구독자 역할을 하는 간단한 모달을 만들 것입니다. 시작하자:

export const Modal = () => {
  const [content, setContent] = useState("no content");
  const [showModal, setShowModal] = useState(false);

  const setMessage = (message) => {
    setContent(message);
    setShowModal(true);
  };
  const clearMessage = () => {
    setContent("");
    setShowModal(false);
  };

  if (showModal) {
    return (
      <div>
        <h2>{content}</h2>
        <button onClick={clearMessage}>Close Modal </button>
      </div>
    );
  }
  return null;
};

그런 다음 메시지 전달을 전담할 이벤트 버스가 필요합니다. 여기있어:


const event = {
  list: new Map(),
  on(eventType, eventAction) {
    this.list.has(eventType) || this.list.set(eventType, []);
    if (this.list.get(eventType)) this.list.get(eventType).push(eventAction);
    return this;
  },

  emit(eventType, ...args) {
    this.list.get(eventType) &&
      this.list.get(eventType).forEach((cb) => {
        cb(...args);
      });
  }
};


여기 이벤트 작업onemit에 대한 더 복잡한 시스템이 있습니다. 다른 이벤트 시스템에 clear, off 등과 같은 다른 이벤트를 추가할 수 있습니다.

이벤트 시스템이 제자리에 있으면 이 이벤트 시스템을 모달에 연결합니다.

export const Modal = () => {
  const [content, setContent] = useState("no content");
  const [showModal, setShowModal] = useState(false);

  const setMessage = (message) => {
    setContent(message);
    setShowModal(true);
  };
  const clearMessage = () => {
    setContent("");
    setShowModal(false);
  };

  useEffect(() => {
    event.on("showModal", setMessage).on("clearAllMessage", clearMessage);
  }, []);
  if (showModal) {
    return (
      <Container>
        <h2>{content}</h2>
        <button onClick={clearMessage}>Close Modal </button>
      </Container>
    );
  }
  return null;

다음으로 퍼즐을 완성하려면 이벤트를 내보낼 Publisher인 최종 조각이 필요합니다.


export const ModalPublisher = {
  message: (content) => {
    event.emit("showModal", content);
  },
  clearAllMessage: () => {
    event.emit("clearAllMessage");
  }
};


알겠습니다. 모든 것이 제자리에 있으면 이제 사용할 수 있습니다App.js.


function App() {
  return (
    <div className="App">
      <Modal showModal={true} />
      <h1
        onClick={() => {
          ModalPublisher.message("this is the content from App");
        }}
      >
        Hello CodeSandbox
      </h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}


결론



이 코드는 아직 생산 준비가 되지 않았지만 다루어야 할 엣지 케이스가 많습니다. 모달과 토스트에 이 패턴을 사용했습니다.

코멘트?


  • 이런 패턴으로 사용하시나요?
  • 이 패턴은 또 어떤 용도로 사용할 수 있습니까?
  • 좋은 웹페이지 즐겨찾기