Hooks API: The Universal Front-End API?

Ryan Carniato
3 min readFeb 3, 2019

--

There already been a lot discussion about React’s Hooks API. It isn’t even officially released, and there are already a lot of opinions about what this means for the future of React and its ecosystem. However, I think Hook’s effect could extend well beyond React.

When React does something every competitor or would be Framework writer pays attention. First wave within a couple days there are new React Hook libraries everywhere. Within a week existing libraries are publishing how they interface with the latest and greatest. Soon after copycat libraries show up. And within no time at all it has been cemented as “the way” to do UI.

To the surprise of no one the proposed Hooks API has had a similar response. React did not invent the patterns they presented in their Hooks API. However, by promoting this approach they have legitimized them. So what? The number of ES6 Class based life-cycle methods Component libraries is too numerous to count.

What makes Hooks interesting is they are borrowed from the other way (Key Value Observables) to manage change in DOM rendering libraries. The approach used by MobX, Vue, Ember, KnockoutJS to name a few. They present themselves as composable primitives but they actually are a manufactured abstraction over React’s top down Component change management. This is actually kind of impressive as it demonstrates that pretty much all JavaScript Declarative UI libraries could sport the same API. Virtual DOM, Real DOM, KVO, Components, Web Components, whatever...

A simple counter with React Hooks:

const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const t = setInterval(() => setCount(c => c + 1), 1000);
return () => clearInterval(t);
}, []);
return <div>Count: {count}</div>;
}

A simple counter with Neverland a Template Literal Web Component Library written Andrea Giammarchi:

const Counter = stardust(() => {
const [count, setCount] = useState(0);
useEffect(() => {
const t = setInterval(() => setCount(c => c + 1), 1000);
return () => clearInterval(t);
}, []);
return html`<div>Count: ${count}</div>`;
})

Or here’s an example with LitHTML with Component Register Hooks:

const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const t = setInterval(() => setCount(c => c + 1), 1000);
return () => clearInterval(t);
}, []);
return html`<div>Count: ${count}</div>`;
}

Or some KVO with no Virtual DOM. How about Solid, one of the top performers on JS Frameworks Benchmark:

const Counter = () => {
const [count, setCount] = useSignal(0);
useEffect(() => {
const t = setInterval(() => setCount(count() + 1), 1000);
useCleanup(() => clearInterval(t));
});
return <div>Count: {count}</div>;
}

Or, Surplus, another top contender using JSX:

const Counter = () => {
const count = S.data(0);
S.effect(() => {
const t = setInterval(() => count(count() + 1), 1000);
S.cleanup(() => clearInterval(t));
});
return <div>Count: {count()}</div>;
}

There are tons more and many predate React Hooks. But regardless of technology choices and how they mechanically work, the abstraction is essentially the same. There is some sort of trackable data and some sort of function closure over a computation (side effect, or memo).

So as a library writer knowing this, couldn’t I just target Hooks as a platform rather than a given Framework?

A library like MobX React Lite is written on top of useState, useCallback, useEffect and useRef from React. It provides MobX capabilities through composed (Higher Order) Hooks to React. But if any library can provide these hooks, then MobX integration could work without additional effort for any library. This could be true for any Hook based extension in the React ecosystem. A factory method could extend them to any work with any library. I’m not sure if this will be a thing. But it seems like something worth trying.

--

--

Ryan Carniato
Ryan Carniato

Written by Ryan Carniato

FrontEnd JS Performance Enthusiast and Long Time Super Fan of Fine Grained Reactive Programming. Member of Marko Core Team. Author of SolidJS UI Library.

No responses yet