brandonhilkert
brandonhilkert

Reputation: 4475

React custom event listener

I'm writing a Chrome extension that places a button next to the "reply" button of each email. And elsewhere on the page is the main React component. When the component loads, I add listeners to a custom event:

  componentDidMount: function() {
    this.listenForFileEmailEvent();
  },

  listenForFileEmailEvent: function() {
    window.addEventListener("fileThisEmail", this.handleFileEmail, false);
  },

I place the button in each email and setup the event:

  $(document).on("click", ".file-this-email", function(e) {
    var email = $(e.target).parents(".gs").find('.gD').first().attr("email");
    var name = $(e.target).parents(".gs").find('.gD').first().attr("name");
    var content = $(e.target).parents(".gs").find(".adP").first().text();

    evt = new CustomEvent("fileThisEmail", {
      detail: {
        name: name,
        email: email,
        content: content
      }
    });

    window.dispatchEvent(evt);
  });

The component is placed in the conversation view of each thread. So, naturally, if you go between the inbox, and then back to a conversion, another component is inserted. And thus the old listeners aren't removed, so multiple events fire the second time.

I tried to add the following before I setup the listener:

  listenForFileEmailEvent: function() {
    window.removeEventListener("fileThisEmail", this.handleFileEmail, false);
    window.addEventListener("fileThisEmail", this.handleFileEmail, false);
  },

But when I inspect the listener events after removing, and prioring to adding it again, it is still there.

So I think there are 2 questions, is there a better way to do this for a rogue button that will live outside the component? And if not, how can I ensure multiple events don't fire for this?

Upvotes: 1

Views: 6595

Answers (1)

rfunduk
rfunduk

Reputation: 30442

I think you'll find that this.handleFileEmail isn't necessarily the same function since you are adding/removing the component.

Try removing the listener in componentWillUnmount instead.

componentWillUnmount: function() {
  window.removeEventListener("fileThisEmail", this.handleFileEmail, false);
}

Upvotes: 3

Related Questions