WebReflection / basicHTML

A NodeJS based, standard oriented, HTML implementation.
ISC License
126 stars 10 forks source link

disconnectedCallback is not invoked #43

Open dios-david opened 5 years ago

dios-david commented 5 years ago

I found that disconnectedCallback() doesn't get invoked when removing a custom element from the DOM.

To be honest, I don't really know what behaviour should I expect here:

Does basichtml have any support for this? (instead of doing document.body.innerHTML = '';)

const { init, HTMLElement } = require('basichtml');
const { customElements, document } = init();

customElements.define('test-component', class TestComponent extends HTMLElement {
    connectedCallback() {
        console.log('connected');
        this.interval = setInterval(() => console.log('tick'), 1000);
    }

    disconnectedCallback() {
        console.log('disconnected');
        clearInterval(this.interval);
    }
});

document.body.innerHTML = '<body><test-component /></body>';
console.log(document.toString());
document.body.innerHTML = '';

// keeping the process alive
process.stdin.on('data', () => {});

As a result of not calling disconnectedCallback, the setInterval() created in connectedCallback keeps ticking in every second.

Console output:

connected
<!DOCTYPE html><html><body><body><test-component></test-component></body></body></html>
tick
tick
tick

(Please forgive me opening issues, there are rather questions than actual issues. I'm just getting familiar with basichtml, which looks awesome as your other projects (e.g. heresy <3))

WebReflection commented 5 years ago

Mind if I ask what are you using basicHTML for? As SSR technology, you never want timers on connected, as example

dios-david commented 5 years ago

I've found this as the simplest example to show that disconnectedCallback wasn't invoked.

BTW I'm experimenting with custom elements, just for fun. These elements supposed to be isomorphic, so in my server bundle window/document/HTMLElement are imported from basicHTML, while in the browser bundle those are provided by the browser itself. In this way I can render my elements on both server/client side, and the server-side rendered elements can rehydrate on the client. So I'm using basicHTML for SSR of my custom elements. I'm familiar with your similar solutions and I know I could just use them as-is, but actually they inspired me a lot to start experimenting with the concept itself and try to build something similar.

I can workaround this issue in many ways, e.g. mocking setTimeout/setInterval on the server-side, or wrapping it in a condition like isSSR/isBrowser, etc. Just ran into this and wanted to give you a heads up about this.