When building applications with Lightning Web Components (LWC), developers need to pass information across components to share state and re-render components. In this post, I’ll share an overview of the different communication patterns along with their perks and use-cases. We’ll look at the three types of exchanges:
- Passing data down the component hierarchy.
- Passing data up the component hierarchy.
- Passing data to components that share no common ancestry.
Passing data down the component hierarchy
There are three techniques for passing data from a parent to a child component; you may either use a public property, a setter or a method. For reference, a child component is a component that’s included in the HTML template of a parent component at design time. At runtime, the child component will be embedded in a sub-DOM tree of the parent component.
A public property is the simplest way to receive data in a child component and requires the least amount of code. A public property is exposed by applying the
Here’s an example of how a parent component updates a
childAttribute public property from a child component. Note how the
childAttribute property name is automatically converted to kebab case (lowercase, dash-separated) when set with an HTML attribute.
Public properties are reactive so the component re-renders whenever one of its public properties is updated. On the downside, you cannot run custom logic when the value changes and the child component should not assign values to its public properties.
Public getters and setters
Public getters and setters behave exactly like public properties when used in a parent component. However, they bring additional flexibility to the child component by allowing you to execute custom logic when retrieving or updating a value. Additionally, a child component is able to set values using its own setters.
Another important difference with public properties is that getters and setters don’t provide persistence out of the box. A common pattern to handle that is to use a “private” property prefixed with an underscore to store the value internally in the child component.
Here’s an example of how a parent component uses a
childAttribute public setter from a child component and saves its value in a
You may call public methods to pass several values to a child component in order to perform an action like a calculation. As opposed to setters, methods allow you to enforce consistency by passing multiple parameters at once.
Here’s an example of how a parent component calls a
calculate public method from a child component:
Methods support asynchronous processing as they can return any type of value including promises.
Passing data up the component hierarchy
You can pass data from a child component to a parent or ancestor with events. Lightning Web Components relies on DOM events (as defined in the standard DOM specification) to propagate data up the component hierarchy.
Here’s an example of how a child component can dispatch a CustomEvent with a contact ID to a parent component:
You can configure an event’s propagation so that it propagates to ancestor components that are not direct parents of a child component. To do so, you can set the
bubbles attribute when creating the event:
You can also stop the event propagation at any time with Event.stopPropagation().
Check out the “Child-to-Parent” recipes from LWC Recipes for various examples of event firing and handling.
Passing data to components that share no common ancestry
Sometimes you need to send data to components that share no common ancestry. For example, you may need to send data to or from a component hosted in a different region of a Lightning page or in a utility bar. This type of communication can be achieved with the Lightning Message Service or with the pubsub module.
Lightning message service
The Lightning Message Service (LMS) is the preferred solution for communicating between components that aren’t in the same DOM tree. LMS also allows communication between the three Salesforce UI technologies: Lightning Web Components, Aura and Visualforce.
LMS provides a publish/subscribe mechanism that allows for the exchange of messages between components. For the sake of brevity and in order not to duplicate documentation, we won’t dive into the technical details of how to publish and subscribe to Lightning messages – but it requires three key steps:
- Declare a message channel using the
- Publish a message using the
publish()function from the
- Subscribe to a message using the
subscribe()function from the
Check out the “Message Service” recipes from LWC Recipes for examples of how to use LMS.
The pubsub module should be used as a last resort alternative in containers that do not support the Lightning Message Service. The module provides a publish/subscribe mechanism for exchanging data across a web page. It’s a functional solution but is not officially supported or actively maintained.
Summing it up: five features for three inter-component communication patterns
That’s a wrap. In this post, we saw an overview of the three types of inter-component communication patterns, along with their respective benefits and use cases:
- Passing data down the component hierarchy with public properties, setters or methods.
- Passing data up the component hierarchy with events.
- Passing data to components that share no common ancestry with the Lightning Message Service or the pubsub module.
Here’s a recap of the different features that you can use to share data across components:
If you’d like to learn more, install and explore our LWC Recipes sample app to see these techniques at work in small code-snippets.
About the author
Philippe Ozil is a Principal Developer Advocate at Salesforce where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full stack developer and enjoys working on DevOps, robotics and VR projects. Follow him on Twitter @PhilippeOzil or check his GitHub projects @pozil.