Skip to content

Instantly share code, notes, and snippets.

@dy
Last active August 13, 2019 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dy/6b78610f13a63876ad250e0401dcf7f8 to your computer and use it in GitHub Desktop.
Save dy/6b78610f13a63876ad250e0401dcf7f8 to your computer and use it in GitHub Desktop.
React vs spect

Same amount of code, same time:

  • no html side-effect restriction allows easily implement portals and get rid of useContext hooks
  • batched state allows simpler effect code
  • aspects integrate better with DOM, can be applied to any elements
  • aspects can be loaded gradually, not as single framework bundle, allowing progressive enhancement
  • aspects cross-cut concerns and can be developed independently
  • references enable transparency for components - allows cross-subscribing
import React, { useEffect, useState } from 'react';
import { render } from 'react-dom'
import { useRoute } from 'wouter';
import { t, useLocale } from 'ttag';
import ky from 'ky';
let rootLang = document.documentElement.getAttribute('lang')
function App ({ lang=rootLang }) {
let [ match, { id } ] = useRoute('user/:id');
let [loading, setLoading] = useState(false)
let [user, setUser] = useState()
let [t, setLang] = useLocale(lang)
useEffect(() => {
setLoading(true)
(async () => {
setUser(await ky.get(`./api/user/${id}`))
setLoading(false)
})()
}, [id]);
return <p>{
!loading ? t`Hello, ${ user && user.name }!` : <>t`Thanks for patience...`<canvas className="spinner"/></>
}</p>;
}
render(document.querySelector('main#app'), App)
import $ from 'spect';
import { route } from 'spect-router';
import { t, useLocale } from 'ttag';
import ky from 'ky';
function main (app) {
let [ match, { id } ] = route('user/:id');
if (!match) return;
app.state(async state => {
state.loading = true
state.user = await ky.get(`./api/user/${id}`);
state.loading = false
}, id);
app.html`<p use=${i18n}>${
app.state`loading` ? `Hello, ${ app.state`user.name` }!` : `Thanks for patience...`;
}</p>`;
}
function preloader (el) {
el.html(h => `${ el.children } ${el.state`loading` && h`<canvas.spinner />`}`, el.state`loading`);
}
function i18n (el) {
useLocale(el.attr`lang` || $(document.documentElement).attr`lang`);
el.text( text => t`${ text }` );
}
$('main#app').use(main, preloader);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment