1

Generally,

In Lightning Web Components (LWC), you should not manipulate the DOM or add event listeners in the constructor. The constructor is called when an instance of the component is created, but before the component is connected to the DOM. This means that the component's DOM is not available yet, so you can't interact with it.

In the salesforce documentation: link, the event listeners are being added from the constructor method.

The code is like below:

// parent.js
import { LightningElement } from "lwc";
export default class Parent extends LightningElement {
  constructor() {
    super();
    this.template.addEventListener("notification", this.handleNotification);
  }
  handleNotification = () => {};
}

Why is the event listener being added in the constructor() here? Am I getting something wrong?

1 Answer 1

3

In the constructor, template is a #document-fragment. In other words, it's safe to work with template directly, because it's already been initialized. However, if you use querySelector or querySelectorAll, you'll find that there are no elements because the render method hasn't been called yet.

I'm not a fan of the example in the link you posted, because it suggests that you can just attach event listeners however you'd like in constructor, but in reality, only template is available to attach events to. This is a technically correct, but misleading, example. You should not ordinarily attempt to attach an event listener before renderedCallback has been called.

You might use addEventListener in a constructor to, for example, attach a click handler that can listen to the entire window, or perhaps a blur handler to do something when the user tabs away from the active component. In most cases, though, you'll want to use renderedCallback as the lifecycle event to listen to to attach events to anything rendered in the template (.html).

4
  • My concern with this is that the rendered callback is called each time rendering happens and the DOM has changes each time. You need to consider how you avoid listener leakage. You need to remove all previous listeners (if any) and (re)register unless you know the elements you added listeners to are always there with every render and never change.
    – Phil W
    Apr 11 at 6:14
  • 1
    @PhilW Untrue. This says: The framework takes care of managing and cleaning up listeners for you as part of the component lifecycle. However, if you add a listener to anything else (like the window object, the document object, and so on), you’re responsible for removing the listener yourself.
    – sfdcfox
    Apr 11 at 13:22
  • @PhilW Also, browsers deduplicate listeners on elements as long as you don't create duplicate functions (e.g. with Function.prototype.bind). It's harder than you think to leak listeners.
    – sfdcfox
    Apr 11 at 13:23
  • Fair comments. My comment was based on the hoops we jumped for adding on window to enable cross-namespace event communication (something LWS helps us avoid these days).
    – Phil W
    Apr 11 at 16:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .