Last week, my friend Chris Ferdinandi wrote a fantastic post about creating a clock with vanilla JS. I want to show you how to do the same thing with Reef, the wonderful anti-framework he created and maintains. It's a simple alternative to modern JavaScript frameworks like React and Vue.

The HTML

Before we do anything, let's look at the markup I started with:

<h1>Clock</h1>

<div id="app">
<p>Please enable JavaScript to use this clock.</p>
</div>

The most important thing to note is that I added a "please enable JavaScript" message inside the #app element. If JavaScript is enabled, we change the content of the #app element so this message isn't seen. If not, the user sees a message informing them what to do.

The JavaScript

Immediately-invoked function expression (IIFE)

First things first, I created an immediately-invoked function expression (IIFE) to contain the rest of my code. This allows me to keep my code outside the global scope and avoid naming conflicts with other scripts. I also opted into strict mode to make my code less error-prone:

;(function () {

"use strict";

})();

Variables

Inside my IIFE, I created my component using Reef:

// Create the component
const app = new Reef("#app", {
data: {
time: new Date().toLocaleString()
},
template: function (props) {
return `<p>${props.time}</p>`;
}
});

The first argument I've passed into the Reef contructor is the element I want to render the component into. I've used #app as my selector.

The second argument is an object literal containing my options. Its data property is the state/data for the component. I've added a time property with the current date and time as a string. To get the date and time, I called the toLocaleString() method on an instantiation of the Date() constructor.

The template property is a function which returns the markup for the component. The props parameter represents the component's state/data stored in the data property. I've returned a paragraph element containing the date/time string. I used a template literal, but if you need to support IE, go with old-school string concatenation.

Functions

Next up, I created a function to update the time property of my data:

/**
* Update the time property in the data
*/

function updateTime () {
app.data.time = new Date().toLocaleString();
}

Reef will reactively update the UI for me whenever I call this function.

Inits & Event Listeners

Finally, I initialized my app:

// Initialize the app
app.render();

// Update the time every second
window.setInterval(updateTime, 1000);

I called Reef's render() method to run an initial render, and used my updateTime() function as the callback for the setInterval() method. I set it to run every second (every 1000 milliseconds).

Wrapping up

There you have it: a simple clock built with state-based UI. I'll be writing more articles like this, because I want to show that it's possible to use state-based UI without the overhead of a massive, bloated framework.

Feel free to check out the demo or view the full source code on GitHub. It's available under the MIT License. ❤️