render() {
return (
<button onclick={this.handleClick}>
Click me
</button>
);
}
handleClick(e) {
doStuff();
this.setState(yolo);
}
handleClick(e) {
doStuff();
this.setState(yolo);
}
render() {
return (
<ChildComponent
handlers={this.props.handlers} />
);
}
handleClick(e) {
this.props.handleClick(e);
}
3 base concepts
undo / redo
No race conditions
Loggable / inspectable evolutions
More composable
exposes observables in some parts of the public API (forms)
import Cycle from '@cycle/core';
import {makeDOMDriver} from '@cycle/dom';
function main(sources) {
const input$ = f(sources.DOM);
const vtree$ = g(input$);
return {DOM: vtree$};
}
Cycle.run(main, {
DOM: makeDOMDriver('#app')
});
function intent(DOM) {
return {
changeWeight$:
DOM
.select('#weight')
.events('input')
.map(ev => ev.target.value),
changeHeight$:
DOM
.select('#height')i
.events('input')
.map(ev => ev.target.value)
};
}
function model(actions) {
return Observable.combineLatest(
actions.changeWeight$.startWith(70),
actions.changeHeight$.startWith(170),
(weight, height) =>
({weight, height,
bmi:
calculateBMI(weight, height)})
);
}
function view(state$) {
return state$
.map(({weight, height, bmi}) =>
div([
renderWeightSlider(weight),
renderHeightSlider(height),
h2('BMI is ' + bmi)
])
);
}
function main({DOM}) {
return {
DOM:
view(model(intent(DOM)))
};
}
Transformations from observables to observables
Effects are described in a pure fashion
Very easy to mock
const requests$ = Rx.Observable
.interval(5000)
.map(() => 'http://example.org/')
Cycle.run(main, {
DOM: myDomMock,
HTTP: myHttpMock
});
Flux
RxJS + react
Redux
Elm
No clear consensus (yet?)
Forget about drivers
Hot observables by default