2

I am working on an Electron project where I use Vue CLI project and the Vue CLI Plugin Electron Builder. Everything works great except a weird bug that I found recently.

Whenever I navigate between pages (Vue Router), the event I listen for from the component mounted() property becomes double. It's actually the N+1 issue.

to describe the issue more clearly, I have two Home.vue and HelloWorld.vue components. From Home.vue component, I am sending an event to the main process whenever clicking a button and listening the event.reply() from the same component mounted() property. It's completely as expected at this stage.

However, whenever I go to the HelloWorld page and switch back to the Home page again and when I click the button to send and receive the event from the main process, I don't only see a single event even though I click one time only but I see two event reply. If I switch between pages again, I'll see three event reply and so on like N+1 issue.

For your convenience, I made a quick GIF that will show the issue clearly.

sending and receiving event from the Electron main process

Home.vue

<template>
  <div class="home">
    <button @click="send()">Home</button>
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      cause: null
    }
  },
  mounted() {
    window.ipcRenderer.on("home:reply", event => console.log(event));
  },
  methods: {
    send() {
      window.ipcRenderer.send("home");
    }
  },
};
</script>

main.js

ipcMain.on("home", event => {
  return event.reply("home:reply");
});

I don't have anything special on the Vue Router and it's just default scaffolding that comes with the Vue CLI. As you can see in the above code snippet, all I am doing is just sending an event when clicking a button and listening for the same event reply from the same component mounted() property.

I also found a similar topic on Stack Overflow but couldn't figure it out myself. I have no clue what's wrong on my code

Md Mazedul Islam Khan
  • 5,318
  • 4
  • 40
  • 66

1 Answers1

3

You need to unregister the event handler when the component is destroyed, otherwise you'll just keep registering the same event handler again and again each time the component is mounted.

mounted() {
  window.ipcRenderer.on('home:reply', this.handleHomeReply)
},

destroyed() {
  window.ipcRenderer.off('home:reply', this.handleHomeReply)
},

methods: {
  handleHomeReply(event) {
    console.log(event)
  }
}
Decade Moon
  • 32,968
  • 8
  • 81
  • 101
  • 1
    This is also why you should always use named functions for your event handlers, rather than the `(ev)=>{...}` style, even though the latter can be very tempting when the `...` bit is short and simple (as it is in the question). – Darren Cook Aug 16 '20 at 17:20
  • Damn, that was it. Thanks man! I didn't find any document about the `ipcRenderer.off()` anywhere and never thought of it really ✌️ – Md Mazedul Islam Khan Aug 16 '20 at 17:45