Component messaging | Lucid.js

J-Path / Component messaging

Introduction 🔗

Lucid allows any component to message any other, regardless of place in the component hierarchy.

While Lucid provides an API for this, cross-component messaging can actually just be as simple as talking from component object to another, directly.

For example, for a child component to call a function that live on its parent component, we could do:

this.parent.data.someFunc();

And that may often be fine. However, a more structured messaging approach is often preferable for several reasons:

  • You can message several components at once (e.g. all sibling components, or all parent/ancestor components)
  • Messages arrive with a clearer trail of which component sent it
  • Since messages will nearly always be sent in response to events, e.g. user interaction, it makes sense to structure message transaction as an event too.

Syntax 🔗

A component can message another via the message() method of the component API.

this.message(xpath[, data1, data2, ...]);

xpath is an  XPath expression targeting the recipient component(s), relative to the sender component.

XPath is used primarily with languages such as XSLT and XQuery, to traverse XML documents. It works similar to CSS selector syntax. If you're unfamiliar with it, try a beginner tutorial.

Any subsequent params passed after xpath are passed along as the message content.

Example 🔗

Say we had a parent component, called Squares, which comprises a series of child Square components.

<div> <Square /> <Square /> <Square /> </div>

When iterating components like this it makes more sense to use repeaters, but we'll do it manually here.

When a square is clicked, it should go red, and revert its sibling components back to the original black. We'll send a message from the newly-clicked component to its siblings to "revert".

Our Square component looks like this.

<style> div { background: #000; width: 80px; height: 80px; display: inline-block; } div.on { background:#f00; } </style> <div></div> <script> this.DOM.onclick = () => { this.DOM.classList.add('on'); this.message('preceding::Square|following::Square', 'revert'); }; </script>

XPath doesn't provide a general sibling "axe" - it can give you preceding siblings or proceding siblings, so we need to use both - separated by the multi-path pipe operator, |.

Our message is simply the string "revert", but we could structure the message however we liked. Now we just need to set up the message receiver code to act on that instruction.

The sending code and receiving code are in the same component, because in our example we're dealing with siblings of the same component type messaging each other.

this.on('message', (comp, msg) => { if (msg == 'revert') this.DOM.classList.remove('on'); });

And that's it!

Did I help you? Feel free to be amazing and buy me a coffee on Ko-fi!