DEV Community

yysun
yysun

Posted on

AppRun Event Directives

Introduction

AppRun is a JavaScript library for building reliable, high-performance web applications using the Elm inspired Architecture, events, and components.

If you are new to AppRun, read the AppRun Book or visit AppRun Docs.

This post introduces a new method of event handling using the event directives.

Event Directives

We have been using events since the first AppRun release to drive the applications which have the logic broken down into three separate parts.

  • State (a.k.a. Model) — the state of your application
  • View — a function to display the state
  • Update — a collection of event handlers to update the state

Take a look at the following application as an example. The count adds up when we click the button.

const view = state => <button onclick={()=>app.run('+1')}>
  Clicks: {state}
</button>;
const update = {
  '+1': state => state + 1;
};
app.start(document.body, 0, view, update);

Every time we click the button, the DOM event is converted to the AppRun events, and then triggers the AppRun event lifecycle:

  • AppRun calls the event handler (+1) to update the state
  • AppRun calls the view function to generate virtual DOM
  • AppRun renders the virtual DOM to the HTML element

The newly released AppRun Directives, allows us to use the Event Directives to run the same steps above without events.

JSX Event Directives

The directives are special HTML attributes that have names starting with $, such as $onclick. They are the extensions to the JSX syntax to simplify the JSX or add extra features.

We can use $onclick to simplify the syntax of publishing AppRun events from

<button onclick={()=>app.run('+1')}>+1</button>

to

<button $onclick='+1'>+1</button>

Most important, the $onclick directive can trigger the AppRun event lifecycle directly without events. It calls the event handler, then calls the view function, and then renders the virtual DOM.

const add = count => count + 1;
const view = count => <button $onclick={add}>
  Clicks: {count}
</button>;
app.start(document.body, 0, view);

You can see, because there are no events in this case, we don't need the update object anymore.

JSX Event Directives are available in V1.x and V2.x already. We recommend using the event directives going forward to reduce the use of the update object.

lit-html

In the AppRun V3 release, AppRun will accept lit-html in addition to JSX and HTML string returned from the view function.

lit-html is the DOM rendering technology that lets us write HTML templates using string literals.

const add = (state, delta) => state + delta;
const view = state => {
  return html`<div>
    <h1>${state}</h1>
      <button @click=${()=>app.run('add', -1)}>-1</button>
      <button @click=${()=>app.run('add', +1)}>+1</button>
    </div>`;
};
app.start(document.body, 0, view, {add});

The html in the example above is the string literal from lit-html. The @click is the way to define the onclick event using lit-html.

BTW, We have used the object shorthand property names: {add} as the update object.

Following the idea of using the JSX event directive to reduce the use of the update object, what can we do when using lit-html?

lit-html Event Directive

The good news is that lit-html also has the directive concept so that we can bring the event directive to lit-html. The directive for lit-html is called run.

The example below shows how to use the run directive to trigger AppRun events.

const add = (state, delta) => state + delta;
const view = state => {
  return html`<div>
    <h1>${state}</h1>
      <button @click=${run('add', -1)}>-1</button>
      <button @click=${run('add', +1)}>+1</button>
    </div>`;
};
app.start(document.body, 0, view, {add});

Also, similar to the JSX event directives, the run directive can trigger the event lifecycle directly without events.

const add = (state, delta) => state + delta;
const view = state => {
  return html`<div>
    <h1>${state}</h1>
      <button @click=${run(add, -1)}>-1</button>
      <button @click=${run(add, +1)}>+1</button>
    </div>`;
};
app.start(document.body, 0, view);

The run directive will:

  • Call the add function
  • Call the view function
  • Render the HTML element (document.body)

Live Demo

Note: AppRun V3 is available on npm as apprun@next.

Have fun!

Top comments (0)