Events Best Practices
We recommend following these best practices when working with events.
To communicate data to elements in the same shadow tree, don’t add
event.detail. The consumer of the event can use the
To communicate data to elements that aren’t in the same shadow tree, use
event.detail. In these cases,
event.target.*doesn’t work because the real target isn’t visible to the listener. (When an event bubbles up the DOM, if it crosses the shadow boundary, the value of
Event.targetchanges to match the scope of the listener. The event is retargeted so the listener can’t see into the shadow tree of the component that dispatched the event.)
If you do use
detailproperty, any listener can mutate that object without the component’s knowledge, which is a bad thing!
It is possible to avoid leaking internal state when using a non-primitive type. Before you add data to the
detailproperty, copy it to a new object or array. Copying the data to a new object ensures that you’re sending only the data you want, and that the receiver can’t mutate your data.
Don’t include the non-primitive from
detail. These values are wrapped in a read-only membrane. In IE 11, when crossing the LWC to Aura bridge, the read-only membrane is lost, which means that mutation can occur.
- Event Propagation
Use events configured with
composed: falsebecause they're the least disruptive. These events don’t bubble up through the DOM and don’t cross the shadow boundary.
Bubbling and composed events are not recommended because they bubble up the entire DOM tree, across shadow boundaries, and through parent components (unless stopped). If you configure an event with
composed: true, the event type becomes part of the component’s public API. It also forces the consuming component and all of its ancestors to include the event as part of their APIs. It's a big API contract to sign up for. If you do use this configuration, the event type should be globally unique.