GitHub

  • Behaviors can be tested by calling actions and then verifying the state.
  • Action : an Action can create an Intent and send it to the Intent Stream
  • A counter can have actions of inc and dec , which will send either {type: ‘inc’} or {type:’dec’} to Intent Stream upon being called.
  • A stream with all of the state’s history will be created, called historyStream .
  • With react-most , we simply define data transformations, then compose them to form our data flow.

react-most – Declarative Monadic Reactive State Container for React

@mattpodwysocki: Reactive Monadic State containers for @reactjs… Kinda cool stuff and yes you can use @ReactiveX / RxJS with it

A Monadic Reactive Composable State Wrapper for React Components

is a simple, 100 LOC Higher Order Component for React. Its only dependencies are most, most-subject, ramda, React, and (optionally, if you prefered) RxJS.

is simple and unidirectional.

, I’ll explain by a simple counter app.

Also, you can refer to:

const counterable = connect((intent$) => { return { sink$: intent$.map(intent => { switch (intent.type) { case ‘inc’: return state => ({ count: state.count + 1 }); case ‘dec’: return state => ({ count: state.count – 1 }); default: return _ => _; } }), inc : () => ({ type: ‘inc’ }), dec : () => ({ type: ‘dec’ }) } })

const Counter = counterable(CounterView) render( < /Most>, document.getElementById(‘app’) );

allows you to model user events, actions, and data as reactive streams. Now you can map, filter, compose, and join those streams to form your application’s state.

, we simply define data transformations, then compose them to form our data flow. There are no variables, no intermediate state, and no side effects in your data flow’s data composition!

statements can make them difficult to compose. Unlike reducers, sinks are reusable observable object.

Wrapper is simply a function and easily composable.

const countBy1 = connect(…) const countBy2 = connect(…) const Counter = countBy1(countBy2(CounterView)) // or const counterable = compose(countBy1, countBy2) const Counter = counterable(CounterView)

Because UI and UI behavior are loosely coupled, you can test a React component by just passing it data. Behaviors can be tested by calling actions and then verifying the state.

let {do$, historyStreamOf} = require(‘../test-utils’) let todolist = TestUtils.renderIntoDocument( < /RxTodoList> < /Most> ) let div = TestUtils.findRenderedComponentWithType(todolist, RxTodoList); do $([()=> div.actions.done(1), ()=> div.actions.done(2), ()=> div.actions.remove(2), ()=> div.actions.done(1)]) return historyStreamOf(div) .take$(4) .then(state => expect(state).toEqual({todos: [{id: 1, text: 5, done: false}]}))

Asynchronous functions, such as Promises, can be converted to a stream and then flat-mapped.

intent$.map(promise => most.fromPromise(promise)) .flatMap(value => /* use the results */)

Transducer is another high-performance, functional way to compose non-monadic data flows.

Writing actions as transducers can improve reusability.

Because we have all actions’ streams, we can easily reproduce the actions at anytime, or get snapshot of the state’s stream and going back in time.

connect(intent$ =>[/* your awesome flow */], { history: true })(App)

as a prop

< /Most>

component.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

GitHub