f5 / unovis

Modular data visualization framework for React, Angular, Svelte, Vue, and vanilla TypeScript or JavaScript
https://unovis.dev
Apache License 2.0
2.29k stars 46 forks source link

Svelte 5 Components Rendered After Destruction #488

Open pingu-codes opened 3 days ago

pingu-codes commented 3 days ago

This error occurs when multiple x/y components are rendered then destroyed/unmounted for new components.

The error is caused by @unovis/ts attempting to render destroyed components in updateContainer. The error itself is Node.appendChild: Argument 1 is not an object. in the re-insertion loop within updateContainer:

  // Re-insert elements to the DOM
for (const c of this.components) {
    this.element.appendChild(c.element)
}

I believe this occurs due to svelte 5's deep reactivity once again. If you have more then one x/y component the first component is destroyed / unmounted and the component.destroyed function is called, this triggers the updateContainer typescript function with one component still remaining, while this is occuring the other component is destroyed but is still present in the config.components array, therefore this loop attempts to append an undefined object.

The fix for this as far as my testing is doing config.components = config.components?.filter((c) => !c.isDestroyed()); before calling updateContainer.

The other problem is the component lifecycle action's destroy function is called before the line.svelte onDestroy callback is called. Since the onDestroy callback is responsible for marking the component as destroyed the lifecycle action doesn't remove the destroyed component.

lee00678 commented 2 days ago

@pingu-codes do you want to add these updates in your existing PR https://github.com/f5/unovis/pull/487?

pingu-codes commented 2 days ago

I've added it in!