为什么在刺激控制器中断开连接
本文最初发表于 Rails Designer
Stimulus 中的断开生命周期方法是三种生命周期方法之一。另外两种是 **initialize** 和 **connect**。当控制器从 DOM 中移除时,会调用断开连接。为此,Stimulus 使用突变观察器来跟踪 DOM 元素。
在断开连接方法中,您可以执行 **拆卸**、清理等操作。执行此操作的原因取决于您的代码,但范围包括防止内存泄漏、维护浏览器性能和防止意外副作用。
让我们看一些例子:
export default class extends Controller { connect() { this.interval = setInterval(() => { console.log("Run, Forrest, run!"); }, 1000); } }
如果不清除间隔,它将继续在后台运行,从而导致内存泄漏。
export default class extends Controller { disconnect() { clearInterval(this.interval); } }
或者如果你使用第三方库,如CodeMirror:
import { EditorView } from "@codemirror/view" export default class extends Controller { connect() { this.editor = new EditorView(); } }
清理很简单:
import { EditorView } from "@codemirror/view" export default class extends Controller { disconnect() { this.editor?.destroy(); } }
如果没有它,任何新的“this.editor”实例都会保持其自己的状态,并且编辑器的 DOM 元素可能会保留在内存中。
让我们再看一个可能会破坏你的浏览器的漏洞。💥
export default class extends Controller { connect() { navigator.mediaDevices.getUserMedia({ video: true }) .then(stream => { this.videoStream = stream; this.element.srcObject = stream; }); } }
如果不停止视频流,它们将继续在后台运行。然后,在运行多个实例时,这将导致高 CPU 使用率,并可能由于资源不足而导致浏览器崩溃。😬
我们来添加一个断开连接,可以吗?
export default class extends Controller { disconnect() { this.videoStream.getTracks().forEach(track => track.stop()); } }