Created
May 28, 2015 09:19
-
-
Save vslinko/c13dd40a4d0199e0570a to your computer and use it in GitHub Desktop.
tried use rx with react
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import Rx from 'rx'; | |
import R from 'ramda'; | |
// dispatcher.js | |
const dispatcher = new Rx.ReplaySubject(); | |
function dispatch(action) { | |
dispatcher.onNext(action); | |
} | |
dispatcher.subscribe(::console.log); | |
// reduceState.js | |
function reduceState(subject, reducer) { | |
const prevState = subject.getValue(); | |
const nextState = reducer(prevState); | |
subject.onNext(nextState); | |
} | |
// inputActions.js | |
function setInputValue(value) { | |
dispatch({type: 'INPUT_CHANGE', value}); | |
} | |
// valueState.js | |
const valueState = new Rx.BehaviorSubject(''); | |
dispatcher.subscribe( | |
action => { | |
console.log('start', action.type); | |
switch (action.type) { | |
case 'INPUT_CHANGE': | |
reduceState(valueState, () => action.value); | |
dispatch({type: 'PING'}); | |
break; | |
case 'PING': | |
console.log('ping'); | |
break; | |
} | |
console.log('end', action.type); | |
} | |
); | |
// component.js | |
function component(render) { | |
return class Component extends React.Component { | |
render() { | |
return render(this.props); | |
} | |
}; | |
} | |
// smartComponent.js | |
function smartComponent(DumbComponent, observable) { | |
return class Component extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {}; | |
} | |
componentWillMount() { | |
this.subscription = observable.subscribeOnNext( | |
state => { | |
this.setState(state); | |
} | |
); | |
} | |
componentWillUnmount() { | |
this.subscription.dispose(); | |
} | |
render() { | |
const props = R.merge(this.props, this.state); | |
return <DumbComponent {...props} />; | |
} | |
}; | |
} | |
// Input.js | |
const Input = component( | |
({valueLink}) => ( | |
<input valueLink={valueLink} /> | |
) | |
); | |
// InputExample.js | |
const InputExample = component( | |
({valueLink, note}) => ( | |
<div> | |
<Input valueLink={valueLink} /> | |
| |
{valueLink.value || <i>no value</i>} | |
| |
<b>{note}</b> | |
</div> | |
) | |
); | |
// SmartInputExample.js | |
const noteState = Rx.Observable.just('Hello World!'); | |
const SmartInputExample = smartComponent( | |
InputExample, | |
Rx.Observable.combineLatest( | |
valueState, noteState, | |
(value, note) => ({ | |
valueLink: {value, requestChange: setInputValue}, | |
note: note | |
}) | |
) | |
); | |
// App.js | |
const App = component( | |
() => ( | |
<SmartInputExample /> | |
) | |
); | |
// index.js | |
export default function renderApplication(container) { | |
React.render(<App />, container); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment