Conditionals | Lucid.js

Lucid.js / Conditionals

Introduction 🔗

Conditionals are Lucid' way of controlling elements or child components within a component that should be output conditionally. That is to say, they should be output (or not) based on some condition.

Syntax 🔗

Conditionals are declared in a component's JavaScript by declaring a conditionals object on the component instance. The object should be a map of selectors to callbacks which should return a boolean - true for "do render" or false for "don't render".

this.conditionals = { '.some #selector': el => { /* ...decider callback... */ } };

The callback is fed a reference to the element being considered as as its first and only argument.

Example 🔗

Let's see conditionals in action. Let's say you have a component whose HTML template is simply:

<div> <p id=para1>This will definitely render</p> <p id=para2>This will conditionally render</p> </div>

We want the p#para2 element to show only if a certain condition is true - in our case, only if the component's data object has a property showP2 equal to true. Here's how:

this.conditionals = { '#para2': el => === true };

Selectors work just like CSS selectors. You can be as specific as you like. Above, we could also have done p:nth-child(2) or p + p to achieve the same result. See Selectors.

The second paragraph will thus render only if the condition is met. If the showP2 property is ever set to true, the conditional will be reprocessed and the element will this time render.

Difference vs. other frameworks 🔗

If you're familiar with, say, Vue or React, you'll have noticed that Lucid does conditional output quite differently. Vue would handle conditional output via the v-if directive on the HTML tag itself, for example, whereas Lucid does everything via a component's JavaScript.

This illustrates one of Lucid' central philosophies: to not clutter HTML templates with invented syntax.

In Lucid, with the exception of variable placeholders, HTML templates are just that - HTML (albeit with invented tag names representing child component templates).

Reprocessing conditionals 🔗

For fully-reactive apps (see Reactivity), conditionals tied to component data will be automatically be automatically reprocessed as and when that component data changes.

We saw an example of this above.

For semi-reactive apps, though. conditionals can instead be reprocessed via the reprocessConds() method of the components API (or its rc() alias).

Here's how this looks:

<div> <p>Show this paragraph?</p> <button onclick=toggle>Toggle</button> </div> <script> = true; this.conditionals = { p: () => }; = () => { = !; this.reprocessConds('p'); //or this.rc('p'); }; </script>

Conditionals and child components 🔗

Conditionals can be used to target child components as well as standard HTML elements. In the conditional's selector, just targed the child component.

<div> <Somechild /> </div>

And then in your JS:

this.conditionals = { Somechild: () => { /* logic... */ } };

As with normal HTML elements, selectors pointing to child components can be as specific as you like. So if you had several instances of Somechild and wanted to conditionalise only one of them, you'd just need to target it with a more specific selector, i.e. by targeting an attribute or perhaps its DOM position, e.g.:

this.conditionals = { 'Somechild:first-of-type': () => { /* ... */ } };

Note that if a child component is initially rendered, then later unrendered (by a false-evaluating conditinal), then later still re-rendered,

Cached reinstatement 🔗

For elements/child components initially rendered by a conditional, then later unrendered (when the condition becomes false), then later re-rendered, it's possible to do this from a cache rather than rendering the element/child component afresh.

This is controlled by the reinsCaching instantiation param. This is set to false by default, meaning conditionalised elements/child components will be reinstated by being freshly rendered, but it can be set to true to enforce caching.

If this param is false, the child component (and any of its own, deeper child components) will be re-rendered, as though it had call its own render() method.

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