Skip to main content

SF-9212 · Scenario · Easy

Pass value from child LWC component to parent component — which type of event do you use?

✓ Verified by Vikas Singhal · Last reviewed 5/19/2026 · Updated for Spring '26

The answer is CustomEvent — but interviewers ask follow-ups about bubbling, payload shape, listener syntax, and when to switch to Lightning Message Service. A complete answer covers all four.

The 60-second answer

Use a custom DOM event: in the child, this.dispatchEvent(new CustomEvent('eventname', { detail: payload })). In the parent’s template, listen with <c-child oneventname={handleEvent}></c-child> — the prefix is on + lowercase event name. Read the payload in the handler via event.detail. Event names must be lowercase with no hyphens. This is the right pattern for parent ↔ child communication. For sibling components or cross-DOM communication, switch to Lightning Message Service (LMS).

The mechanic

Child — dispatch the event

// childComponent.js
import { LightningElement } from 'lwc';

export default class ChildComponent extends LightningElement {
    handleClick() {
        const payload = { id: '001xx000003DGb2', name: 'Acme Corp', amount: 50000 };

        const evt = new CustomEvent('selectaccount', {
            detail: payload
            // bubbles: false (default), composed: false (default)
        });

        this.dispatchEvent(evt);
    }
}
<!-- childComponent.html -->
<template>
    <button onclick={handleClick}>Select Acme</button>
</template>

Parent — listen and read the payload

<!-- parentComponent.html -->
<template>
    <c-child-component onselectaccount={handleAccountSelected}></c-child-component>
    <p>Selected: {selectedName}</p>
</template>
// parentComponent.js
import { LightningElement, track } from 'lwc';

export default class ParentComponent extends LightningElement {
    selectedName;

    handleAccountSelected(event) {
        const { id, name, amount } = event.detail;
        this.selectedName = name;
        // do something with id / amount
    }
}

Rules interviewers test for

RuleWhy it matters
Event name lowercase, no hyphens (selectaccount, not select-account)LWC framework requirement; HTML attribute names are case-insensitive
Listener prefix is on + eventname<c-child onselectaccount>; not onSelectAccount
Payload goes in detailAlways — never a top-level property
bubbles: false by defaultEvent stops at the parent unless you opt in
composed: false by defaultEvent doesn’t cross Shadow DOM unless you opt in
Don’t mutate detail after dispatchReactivity is one-way; pass a shallow clone for safety

When to opt into bubbling

Set bubbles: true when the event needs to reach a grandparent, not just the direct parent:

this.dispatchEvent(new CustomEvent('selectaccount', {
    detail: payload,
    bubbles: true,
    composed: false  // still confined to LWC DOM tree
}));

composed: true lets the event cross Shadow DOM boundaries — needed if you have nested Aura wrapping LWC, or if the listener is outside the component’s shadow root. Use sparingly; it can leak events to unintended listeners.

When to switch to Lightning Message Service (LMS)

Use LMS when the components are not in a parent-child hierarchy — sibling, in different sections of the same page, or in a Utility Bar.

// senderComponent.js
import { publish, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/RecordSelected__c';
import { LightningElement, wire } from 'lwc';

export default class SenderComponent extends LightningElement {
    @wire(MessageContext) messageContext;

    handleSelect(id) {
        publish(this.messageContext, RECORD_SELECTED_CHANNEL, { recordId: id });
    }
}
// receiverComponent.js
import { subscribe, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/RecordSelected__c';

export default class ReceiverComponent extends LightningElement {
    @wire(MessageContext) messageContext;
    subscription = null;

    connectedCallback() {
        this.subscription = subscribe(
            this.messageContext,
            RECORD_SELECTED_CHANNEL,
            (msg) => { this.handle(msg); }
        );
    }
}

LMS works across Aura/LWC and across Utility Bar/Main Region. CustomEvent doesn’t.

Decision matrix

Communication directionRight tool
Child → ParentCustomEvent (no bubbling needed)
Child → GrandparentCustomEvent with bubbles: true
Parent → Child@api public property or method on the child
Sibling → SiblingLightning Message Service
LWC ↔ AuraLMS, or pubsub library if pre-LMS
Cross-page tabLMS

Anti-patterns

  • new Event('name') instead of new CustomEvent('name', { detail }) — vanilla Event has no payload mechanism.
  • Camel-case event name'selectAccount' works in dev but breaks the framework attribute parser; always lowercase.
  • Listener as a property assignment (this.template.querySelector('c-child').onselectaccount = handler;) — works but kills LWC’s declarative reactivity. Use template syntax.
  • Using pubsub.js — the old Aura-era library. Salesforce now recommends LMS for everything non-parent-child. Don’t suggest pubsub in a 2026 interview.
  • Storing huge payloads in detail — passes by reference; mutating downstream confuses the source. Pass a JSON clone for anything you can’t control.

How to answer in 30 seconds

“A custom DOM event — child does dispatchEvent(new CustomEvent('eventname', { detail: payload })); parent listens declaratively with onevenname={handler} in the template. Event names are lowercase, payload goes in detail. For non-parent-child communication use Lightning Message Service.”

How to answer in 2 minutes

Walk the dispatch + listen mechanic, hit the four interview rules (lowercase name, on prefix, detail payload, bubbling default off), explain the bubbles/composed flags for crossing component or Shadow DOM boundaries, and finish with the decision matrix that picks CustomEvent vs @api vs LMS.

Likely follow-up questions

  • What’s the difference between bubbles: true and composed: true?
  • How would you pass data from parent to child?
  • When would you use Lightning Message Service instead?
  • Can a child component call a method on its parent?
  • What happens to events when the component is destroyed?

Verified against: LWC Developer Guide — Communicate with Events, Lightning Message Service. Last reviewed 2026-05-19.