xmppjs / xmpp.js

XMPP for JavaScript
ISC License
2.18k stars 371 forks source link

Issue with multiple event listeners #934

Closed nicolinho22 closed 2 years ago

nicolinho22 commented 2 years ago

Hi everyone,

I have a chat app which is written in React. I've defined multiple hooks which handle different protocols like useMultiUserChat or even specific stanza type like useIqStanzaRequest.

I have the following code:

  const useIqStanzaRequest = (callback: (stanza: Stanza) => void) => {
      const requestId = useRef<string>();

      const onStanzaHandler = (stanza: Stanza) => {
          if (stanza.is('iq') && stanza.attrs.id === requestId.current) {
              callback(stanza);
          }
      };

      const request = (stanza: Stanza) => {
          const id = uuidv4();
          const stanzaWithId = { ...stanza };

          stanzaWithId.attrs.id = id;
          requestId.current = id;

          xmpp()?.send(stanzaWithId);
      };

      useXmppEvent('stanza', onStanzaHandler);

      return request;
  };

  export default useIqStanzaRequest;

In useMultiUserChat hook, I have another useXmppEvent('stanza', onStanzaHandler), so I have multiple listeners attached to a stanza event. It seems this is either problematic for this library, or I'm not seeing something. The useXmppEvent hook looks like this:

  const useXmppEvent = (event: string, callback: (...args: any[]) => void) => {
      const error = useSelector((state: RootState) => state.xmppConnection.error);
      const isClientSet = useSelector((state: RootState) => state.xmppConnection.isClientSet);

      useEffect(() => {
          if (!error && isClientSet) {
              xmpp()?.on(event, callback);
              return () => {
                  xmpp()?.removeListener(event, callback);
              };
          }
      }, [event, callback, error, isClientSet]);
  };

  export default useXmppEvent;

I would really appreciate some help as I'm already stuck on this for quite some time.