I'm new to web components, and I've noticed some examples set the dom in the custom-element's constructor, while others do it in the connectedCallback. As both seem to work fine(although I tried only Chrome), I assume the main difference is the case in which a user creates the element in js and not attaching it to the page?
I guess the main question here is whether I'm missing some other reason to prefer one method over the other.
Thanks.
In the constructor
, it's safe to
In the constructor
, you are not allowed (amongst other things)
...because those might not be present in the non-upgrade case, and definitely won't be present when you dynamically create your custom element using either document.createElement('my-custom-element')
or new MyCustomElement()
.
constructor
In the constructor
, you probably don't want to
document
, window
), because these are the kind of listeners you should clean up in your component's disconnectedCallback
(which will be also be called when e.g. your component is moved in the DOM, so after removing them in the disconnectedCallback they need to be re-added when re-connecting).Attaching these listeners in the constructor and properly cleaning them up in the disconnectedCallback
results in missing listeners once your component gets removed from (and later re-added), or moved in, the DOM.
You need to be aware of the custom element lifecycle to not fall into otherwise obvious pitfalls, which include:
constructor
and have included those in your component's observedAttributes
, remember this will immediately trigger the attributeChangedCallback
for those attributes, even if your element is not yet connected (a.k.a. in the DOM).connectedCallback
.In part, these best practices and rules follow https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance, in other parts they deviate from recommendations done there in the spec.
Specifically I disagree on the following (given the scope for the listeners is outside the component), for the reasons I gave above.
In general, the constructor should be used to set up initial state and default values, and to set up event listeners and possibly a shadow root.