Reputation: 55
Why doesn't child method Ondestroy() invoke after removing of a parent component from DOM?
App.svelte
<script>
import Child from "./child.svelte";
let compRef;
</script>
<button on:click={() => compRef.parentNode.removeChild(compRef)}>remove</button>
<div bind:this={compRef}>
<Child />
<Child />
<Child />
</div>
Child.svelte
<script>
import { onMount, onDestroy } from "svelte";
onDestroy(()=> console.log("Child was destroyed!"))
</script>
<h1>
Child
</h1>
Upvotes: 0
Views: 810
Reputation: 184622
onDestroy
has nothing to do with whether the element is in the DOM. Components can also have no elements at all.
The callback is for cleaning up any event listeners and other things not managed by Svelte. The function will be called automatically if Svelte removes a component. If you instantiated a component, you have to call $destroy
manually.
Your example looks like a case for using a simple {#if}
, that way Svelte will destroy the component when the condition is false
.
Upvotes: 0
Reputation: 7699
comRef
holds a reference to the div
element, that's not a component{#if}
block and set the condition to false
<script>
import Child from "./child.svelte";
let condition = true;
</script>
<button on:click={() => condition = false}>remove</button>
{#if condition}
<div>
<Child />
<Child />
<Child />
</div>
{/if}
or, if the wrapper was a component, it could alternatively also be done by calling .$destroy()
REPL
<script>
import Child from "./Child.svelte";
import Parent from "./Parent.svelte";
let compRef
</script>
<button on:click={() => compRef.$destroy()}>remove</button>
<Parent bind:this={compRef}>
<Child />
<Child />
<Child />
</Parent>
Check the console to see, that in both cases the onDestroy
callback will run
Upvotes: 1