Beside writing my thoughts on V8 optimizing a React Hooks pattern, it’d be silly to not use such optimization myself for my never-React related projects, and this is what I’ve done over the past weekend.

Simplifying the already simple

As previously mentioned and tweeted, the introduction of hooks, especially the useState one, is nothing really new to hyperHTML, ’cause that’s what always happened per each render or update call, either through callbacks or components.

import {wire} from 'hyperhtml'; function Counter() {

const view = wire();

return function setCount(count) {

return view`

<p>You clicked ${count} times</p>

<button onclick=${() => setCount(count + 1)}>

Click me

</button>

`;

}(0);

}

Live on Code Pen, above snippet already shows the basic mechanism behind hyperHTML, but it is true that if you want to handle more states, you either use an object, as in this other live demo, or things become a bit complicated.

Hiding details through Hooks

Instead of remembering to update the view whenever a single variable changes, forced to also keep in mind that any variable could change in that scope, Hooks could make the implicit invocation of the outer callback, an elegant solution that doesn’t need much explanation.

import stardust, {html, useState} from 'neverland'; const Counter = stardust(() => {

const [count, setCount] = useState(0);

return html`

<p>You clicked ${count} times</p>

<button onclick=${() => setCount(count + 1)}>

Click me

</button>

`;

});

We can use any amount of states we need, through the soon-to-be-optimized Array destructuring pattern, forgetting to manually invoke the update(..) callback passing along any new value, and I think this is pretty cool.

Wait … where is the Component ?

Well, there is no component. You can node.appendChild(Counter()) and be done for the day. That’s indeed my favorite part about hyperHTML, it’s 100% DOM based, and DOM is also in this case what you get out.

All hyperHTML cares about is to map a unique Template Literal to a parsed tree of DOM operations that updates lightning fast, but of course if you need to perform something else only after all new properties have changed, you can use the useEffect(callback) hook too.

That’s because …

useEffect, useReducer, and useRef available too

“Go Big or Go Home”, I’ve told myself when I’ve wrapped in less than 50 LOC the useState handy pattern, so that in less than 70 I’ve shrunk in the rest, and you can see more about the API in the repository, or test it live.

What about haunted ?



import { component, useState } from ' import { wire } from ' hyperhtml ' import { component, useState } from ' @matthewp/haunted ' function Counter(el) {

const [count, setCount] = useState(0);

return wire(el)`

<div id="count">${count}</div>

<button onclick=${() => setCount(count + 1)}>

Increment

</button>

`.valueOf();

} customElements.define('my-counter', component(Counter));

As you can see live, we could use haunted to have a similar behavior via hyperHTML, but the need for Custom Elements, Shadow DOM, and all related polyfills, makes it a no-go compared to Neverland which is less than~7Kb, including hyperHTML with it, hence with zero external dependencies, and no need for Custom Elements or Shadow DOM at all, which makes it compatible down to IE9, without much tooling needed.

Experimental after all 😉

Not only because React Hooks are also still experimental, I want to see first what the community thinks about Neverland or what it could create with it.