ariman
ariman

Reputation: 55

Svelte: Child method Ondestroy() doesn't invoke after removing of a parent component

Why doesn't child method Ondestroy() invoke after removing of a parent component from DOM?

REPL

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

Answers (2)

brunnerh
brunnerh

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

Corrl
Corrl

Reputation: 7699

  1. comRef holds a reference to the div element, that's not a component
  2. Manipulating the DOM directly in Svelte is usually not a good idea. If you want to remove the elements from the DOM either wrap them in an {#if} block and set the condition to false
    REPL
<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

Related Questions