Skip to content

Instantly share code, notes, and snippets.

@robbestad
Last active September 29, 2016 07:25
Show Gist options
  • Select an option

  • Save robbestad/2fefce0b3dcc87361ac7da9dda18a6de to your computer and use it in GitHub Desktop.

Select an option

Save robbestad/2fefce0b3dcc87361ac7da9dda18a6de to your computer and use it in GitHub Desktop.
/*
* I importseksjonen bruker vi Inferno i stedet for React
* Vi bruker også MobX for tilstandskontroll.
* https://mobxjs.github.io/mobx/refguide/api.html
* MobX er et enkelt men kraftig verkøy for å kontrollere og oppdatere
* tilstand i applikasjonen din. Den virker slik at du definerer tilstandsvariabler
* som skal observeres for endringer, og når endringer skjer oppdateres endringene
* automatisk. Dette i motsetning til f.eks. velkjente Redux hvor du må ivareta
* tilstandsendringer mer eksplisitt og manuelt.
*
* Det er verdt å merke seg at vi normalt ville ha splittet opp denne appen
* i action-filer, store-filer etc, men for eksempelets skyld er hele
* appen skrevet i en fil
*/
import Inferno, {createVNode, createBlueprint} from 'inferno';
import {render} from 'inferno-dom';
import Component from 'inferno-component';
import createElement from 'inferno-create-element';
import {observer} from "mobx-inferno";
import {autorunAsync, observable, action} from 'mobx'
import times from 'lodash.times';
/*
* Dette er en action vi skal bruke for
* å simulere en asynkron fetch. Etter 2,5 sekunder får du
* tittelen tilbake.
*/
function fetchHeadlineAsync() {
return new Promise(resolve => {
setTimeout(() => {
const values = [
'Inferno Boilerplate',
'Frameworks are cool',
'JavaScript all the things'
];
resolve([{value: values[~~(Math.random() * values.length)]}])
// ~~ er en bitwise operator (dobbel bitwise not), brukt her som erstatning for Math.floor.
// Denne metoden er vesentlig raskere enn Math.floor og har fordelen at den
// alltid returnerer et tall (aldri NaN).
}, 2500);
});
}
/*
* Her setter vi opp to stores med actions i hver
*/
class TitleStore {
@observable title;
@observable fetchDisabled;
/*
* Decorators er en eksperimentell feature som er tilgjengelig via Babel transpiler.
* https://github.com/wycats/javascript-decorators
* En decorator er en funksjon som lar oss legge på funksjoner på en variabel, så i dette
* tilfellet sier vi at vi har to variabler (title og fetchDisabled) som er definert som
* observables, og derved er utvidet med funksjonalitet definert i observable-funksjonen.
* Hvis du vil kan du erstatte `@observable title` med `title = observable({})`
*/
constructor(title = '') {
this.title = title;
this.fetchDisabled = false;
}
// Legg merke til at når brukeren klikker på oppdater-knappen så gråes knappen ut
// inntil operasjonen er fullført
@action setTitle = (title) => {
this.title = title;
};
@action fetchData = () => {
this.fetchDisabled = true;
fetchHeadlineAsync().then(res => {
this.title = res[0].value;
this.fetchDisabled = false;
});
}
}
const titleStore = new TitleStore('Inferno');
class NumberStore {
@observable number;
constructor() {
this.number = 1;
}
@action update = () => {
this.number = ~~(Math.random() * 100);
};
}
const numberStore = new NumberStore();
/*
* Blueprint er et konsept som lar deg skape effektive predefinerte virtuelle noder
* Dette er et av mange tricks som gjør Inferno så rask
*/
const template = createBlueprint({
tag: 'div',
children: {arg: 0}
});
/*
* Her lager vi to komponenter med kjent JSX-syntax. JSX er
* ikke nødvendig i Inferno, men er lagt til for å tekkes React-utviklere
*/
@observer
class Row extends Component {
render() {
return (<div class="row center-xs">
{times(6, String).map(i => {
return (
<div class="col-xs-2">
<div class="box"
style={{backgroundColor: `#${(Math.random() * numberStore.number ).toString(16).slice(2, 8)}`}}>
{numberStore.number * ~~(Math.random() * (100))}
</div>
</div>
)
})}
</div>)
}
}
const Rows = times(60, String).map((i) => {
return <Row />
});
@observer
class App extends Component {
render() {
return <div>
{template(
<div>
<div class="row center-xs navbar">
<div class="col-xs-12">
<div class="box">
<h1>{titleStore.title}</h1>
</div>
</div>
</div>
<div class="row center-xs">
<div class="col-xs-12">
<div class="box pat pab">
<button type="button" class="btn-default"
disabled={titleStore.fetchDisabled}
onClick={titleStore.fetchData}>Fetch Title Async
</button>
</div>
</div>
</div>
{Rows}
</div>)}
</div>
}
}
/*
* Her kjøres koden. Intervallet sørger for at tallene konstant blir oppdatert
*/
setInterval(()=>{
numberStore.update();
},1);
/*
* MobX, som brukes i denne eksempelappen, har et konsept kalt Reactions som lar deg
* inspisere endringer
*/
autorunAsync(() => {
console.log("Title changed: " + titleStore.title)
});
/*
* Til slutt så rendrer vi koden (på samme måte som i React)
*/
render(
createElement(App),
document.getElementById('app')
);
/*
* For sammenligning er tilsvarende app skrevet i React tilgjengelig via
* https://gist.github.com/svenanders/46154161051ef325a9b53b2fb776d675
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment