DEV Community

Rails Designer
Rails Designer

Posted on • Originally published at railsdesigner.com

Why Disconnect in Stimulus Controller

This article was originally published on Rails Designer


The disconnect lifecycle method in Stimulus is one of three lifecycle methods. The other two are initialize and connect. Disconnect gets called when the controller is removed from the DOM. For this, Stimulus uses mutation observers to track DOM elements.

Within the disconnect method you can do your teardown, clean up and whatever. The reasons to do this depends on your code, but range from preventing memory leaks, maintaining browser performance and preventing unexpected side effects.

Let's look at some examples:

export default class extends Controller {
  connect() {
    this.interval = setInterval(() => {
      console.log("Run, Forrest, run!");
    }, 1000);
  }
}
Enter fullscreen mode Exit fullscreen mode

Without clearing the interval, it will continue running in the background, causing a memory leak.

export default class extends Controller {
  disconnect() {
    clearInterval(this.interval);
  }
}
Enter fullscreen mode Exit fullscreen mode

Or if you use a third-party library, like CodeMirror:

import { EditorView } from "@codemirror/view"

export default class extends Controller {
  connect() {
    this.editor = new EditorView();
  }
}
Enter fullscreen mode Exit fullscreen mode

Clean up is simple:

import { EditorView } from "@codemirror/view"

export default class extends Controller {
  disconnect() {
    this.editor?.destroy();
  }
}
Enter fullscreen mode Exit fullscreen mode

Without it any new instance of this.editor maintains their own state and the editor's DOM elements might remain in memory.

Let's look at one more that could possibly break your browser. 💥

export default class extends Controller {
  connect() {
    navigator.mediaDevices.getUserMedia({ video: true })
      .then(stream => {
        this.videoStream = stream;
        this.element.srcObject = stream;
      });
  }
}
Enter fullscreen mode Exit fullscreen mode

If you don't stop the video-streams they will continue to run in the background. Then with multiple instances running this will result in high CPU usage and potentially crash the browser due to the lack of resources. 😬

Let's add a disconnect, shall we?

export default class extends Controller {
  disconnect() {
    this.videoStream.getTracks().forEach(track => track.stop());
  }
}
Enter fullscreen mode Exit fullscreen mode

With these examples, I hope you will become a good citizen and clean up after yourself! 😊

Top comments (1)

Collapse
 
railsdesigner profile image
Rails Designer

Have you ever gotten a memory leak or crashed user's browser with faulty JS? 😬