Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The whole point is to make it simple to trigger code and to be interoperable. Then you write whatever code you want to implement the component.

Web components are not analogous to frameworks because frameworks tightly couple the component interface and lifecycle hooks with the component implementations. Those are properly decoupled in web components and you bring whatever rendering layer you prefer.



Yes but their choice to abandon constructors as a primary part of the lifecycle means that adding some kind of member field to the class will leave it inherently uninitialized in the `connectedCallback`. All fields basically have to be declared as `| undefined` if you're using typescript, which leads to reall ugly code:

    class MyComponent extends HTMLElement
    {
        private width: number | undefined; // must be | undefined or
                                           // you'll get a typescript error
        constructor()
        {
            // useless, unpredictable
        }

        connectedCallback()
        {
            this.initAttributes();
            // using this.width will still require an undefined check at some point
        }
   
        initAttributes()
        {
            this.width = Number(this.getAttribute('width'));
        }
    }
If you could reliably load attributes in the constructor instead of being forced to do everything in connectedCallback (or even better, load them automatically with decorators), it would make typescript implementations much cleaner. Just some way to validate attributes before connectedCallback, or work with typescript guarantees would make this much more attractive


The constructor is a part of the lifecycle, and always has been. It wasn't abandoned.

The lifecycle of custom elements reflects the behavior of the HTML parser and DOM APIs. Attributes aren't consistently available in the constructor because the HTML parser is streaming and may yield to the main thread at any time. So the element is constructed first, possibly before attributes are parsed. Attribute also aren't available because when element are constructed imperatively they will never have attributes at first, ie:

    // ctor is called, no attributes!
    const el = document.createElement('my-element'); 
    // now there will be an attribute:
    el.setAttribute('width');
You also shouldn't ever consider attributes to be fixed in a web component, since they may be added and removed at any time, and of course may never be set in the first place. You should implement attributeChangedCallback() and give your element defined behavior for any set of possible attributes.

Or you can use a helper library like Lit which does let you declare and consume your attributes via decorators.


I understand all these things, I think they are weaknesses. They make web components less generally useful, and really only useful for one thing. Constructors are only useful for dependency injection.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: