disconnected()
To explicitly run a callback when a component disconnects from the DOM, use the disconnected() lifecycle callback.
Note: The connected()
lifecycle callback already takes down event listeners and other Flow
objects when a component disconnects from the DOM. The disconnected() callback should not be used in these cases; it is intended only for explicit side effect of disconnecting a custom element.
Syntax
disconnected();
disconnected(callback);
Parameters
- callback optional
- An optional callback to run when the component disconnected (i.e. is removed) from the DOM. The callback is ran inside a monitored context for type "undo", which cleans up the next time the component disconnects (not when the component reconnects).
Return value
A Flow
object that triggers anytime the component disconnects.
Details
The disconnected() lifecycle callback is available anywhere inside the <script>
section of a component definition. The native web component equivalent is the .disconnectedCallback() method. However, side effects managed inside the callback are safe from memory leaks; a monitored context is set up for every call, and the previous monitored context is taken down right before a new one is set up. In practice, this means it becomes much easier to set up e.g. event listeners (using when()
) and other flows because they are automatically taken down.
It can also be utilized purely for its return value, so that it may be passed to .until()
or used in conjunction with await. As such, the callback parameter is optional.
Unlike connected()
, it does not retroactively fire if the component has already previously disconnected. It only only triggers for future disconnects.
Examples
When-less listeners
Let's try to write a component with an event listener, without using when() (or the inline @event
syntax). To do this, we'll use the connected() handler, the traditional .addEventListerner() call to attach the listener, and then their counterparts disconnected() and .removeEventListener() to take them back down. This might look something like:
<title>click-counter</title>
<meta attribute="count" type="number">
<template>
<button>Clicks: {{ $.count }}</button>
</template>
<script>
const button = query('button');
function increment(){
$.count += 1;
}
connected(() => {
button.addEventListener('click', increment);
});
disconnected(() => {
button.removeEventListener('click', increment);
});
</script>
This is, however, an overly verbose way to do this. when()
is flow-based, and flows participate in type "undo" monitored contexts. In other words; when using when() inside a lifecycle callback, then the callback can "see" the listener and take it down when appropriate. Using .addEventListener() sidesteps this system, which then means we need to specify the disconnected() callback to avoid the listener leaking.
See also