custom element setup: constructor vs connectedCallback
Asked Answered
T

1

12

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.

Torrefy answered 29/1, 2020 at 15:10 Comment(1)
Could you give examples of both scenarios?Flask
A
18

Best practices and rules for custom element constructors

What's safe to do in the constructor

In the constructor, it's safe to

  • create the shadow root;
  • create and append elements *;
  • attach event listeners to those elements (scoped to your own ShadowDOM);
  • create attributes * (which might still be a bad idea because in the dynamic creation case this might come unexpected).

What you cannot do in the constructor

In the constructor, you are not allowed (amongst other things)

  • to read any attributes you haven't created beforehand...
  • to access child elements...

...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.

What's unwise to do in the constructor

In the constructor, you probably don't want to

  • attach event listeners to elements outside of the component's shadow DOM (like e.g. document, window), because these are the kind of listeners you should clean up in your component's disconnectedCallback (which will be called when e.g. your component is moved in the DOM).

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.

*Pitfalls and things to be aware of

You need to be aware of the custom element lifecycle to not fall into otherwise obvious pitfalls, which include:

  • If you add attributes in the 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).
  • If you create and append other custom elements into your component's shadow DOM, remember this will trigger those components' 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.

Amadus answered 29/1, 2020 at 15:17 Comment(5)
Helpful diagram of all (callback)methods: andyogo.github.io/custom-element-reactions-diagramKampala
What about setting attributes on / adding listeners to the element itself (this)? is that better done in the constructor or connectedCallback?Broadtail
@ᆼᆺᆼ constructor, for the same reasons.Amadus
@Amadus Hm I have tried, but it doesn't work in the constructor, only in connectedCallbackBroadtail
Ask a question then, including your code and an exact description of what doesn't work as expected. Adding attributes is technically possible in the constructor, but discourages, as in the dynamic creation process the element is generally expected to not have any.Amadus

© 2022 - 2024 — McMap. All rights reserved.