Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Thinking Reactive while writing JavaScript

Thinking Reactive while writing JavaScript

Talk about Reactive programming in JavaScript. What is reactive programming, what are our choices, how to make React reactive, intro to Cycle.js

Ivan Jovanovic

October 20, 2017
Tweet

More Decks by Ivan Jovanovic

Other Decks in Programming

Transcript

  1. • External service calls • Better performance • Highly testable

    • Abstraction over all async processes • Predictable code • Extendable code
  2. Reactive programming in JS • RxJS - the most popular,

    biggest • MostJS - best performance • Bacon.js • XStream - the smallest
  3. +

  4. + +

  5. Features • Functional (just write pure functions) • Reactive •

    Testable • Composable • Explicit dataflow • Made for large codebases
  6. Drivers - side effects • HTTP • DOM • WebSockets

    • Local storage driver • HTML5 Notifications driver • …
  7. Cycle.js official packages • DOM - collection of drivers that

    work with DOM; it has DOM driver and HTML driver, based on snabdom virtual DOM library • History - driver for History API • HTTP - driver for HTTP requests, based on superagent • Isolate - function for making scoped dataflow components • Most-run - `run` function for apps made with `most` • Run - `run` function for apps made with `xstream` • RxJS-run - `run` function for apps made with `rxjs`
  8. import xs from 'xstream'; import { run } from '@cycle/run';

    import { div, button, p, makeDOMDriver } from '@cycle/dom'; function main(sources) { const action$ = xs.merge( sources.DOM.select('.decrement').events('click').map(ev => -1), sources.DOM.select('.increment').events('click').map(ev => +1) ); const count$ = action$.fold((acc, x) => acc + x, 0); const vdom$ = count$.map(count => div([ button('.decrement', 'Decrement'), button('.increment', 'Increment'), p('Counter: ' + count) ]) ); return { DOM: vdom$, }; } run(main, { DOM: makeDOMDriver('#main') });
  9. function main(sources) { const action$ = xs.merge( sources.DOM.select('.decrement').events('click').map(ev => -1),

    sources.DOM.select('.increment').events('click').map(ev => +1) ); const count$ = action$.fold((acc, x) => acc + x, 0); const vdom$ = count$.map(count => div([ button('.decrement', 'Decrement'), button('.increment', 'Increment'), p('Counter: ' + count) ]) ); return { DOM: vdom$, }; }
  10. View + CSS const style = { backgroundColor: 'blue', width:

    '60px', height: '60px' } const vdom$ = count$.map(count => div([ button('.decrement', { style }, ’Decrement’), button('.increment', { style }, ’Increment’), p('Counter: ' + count) ]) );
  11. import { makeHTTPDriver } from ‘@cycle/http'; function main(sources) { const

    request$ = xs.periodic(1000) .mapTo({ url: 'http://localhost:3000', category: 'api', }); const vdom$ = sources.HTTP.select('api') .flatten() .map(res => res.body) .startWith({ response: ‘’ }) .map(result => div([ h2('.label', `Response from the server: ${result.response}`) ]) ); return { DOM: vdom$, HTTP: request$ }; } run(main, { DOM: makeDOMDriver('#main'), HTTP: makeHTTPDriver() });
  12. function main(sources) { const request$ = xs.periodic(1000) .mapTo({ url: 'http://localhost:3000',

    category: 'api', }); const vdom$ = sources.HTTP.select('api') .flatten() .map(res => res.body) .startWith({ response: ‘’ }) .map(result => div([ h2('.label', `Response: ${result.response}`) ]) ); return { DOM: vdom$, HTTP: request$ }; }
  13. const vdom$ = sources.HTTP.select('api') .flatten() .map(res => res.body) .startWith({ response:

    '' }) .map(result => div([ h2('.label', `Response: ${result.response}`) ]) );
  14. import isolate from '@cycle/isolate'; const sources = {DOM: sources.DOM}; const

    childComponent = isolate(Component)(sources); const childComponentVDom$ = childComponent.DOM; const childComponentValue$ = childComponent.value;
  15. Conclusion • Old paradigm with the new usage • Not

    for everyone • Perfect for real time apps that require high performance • Testable, predictable code • One interface for all async processes