babygau babygau - 2 months ago 13
Javascript Question

How to bind React state to RxJS observable stream?

can someone help me how to bind React State to RxJS Observable? I did sth like

componentDidMount() {
let source = Rx.Observable.of(this.state.val)
}


The ideal result is, whenever
this.state.val
updated (via
this.setState(...)
)
source
get updated too, so I can combine
source
with other RxJS observable stream.

However, in this case,
source
only get updated once, even after
this.state.val
is updated and component is re-rendered.

// Ideal result:
this.state.val = 1
source.subscribe(val => console.log(x)) //=> 1
this.state.val = 2
source.subscribe(val => console.log(val)) //=> 2

// Real result:
this.state.val = 1
source.subscribe(val => console.log(x)) //=> 1
this.state.val = 2
source.subscribe(val => console.log(val)) //=> 1 ???WTH


It might be because
componentDidMount()
only invoked once in React lifetime. so I move
source
to
componentDidUpdate()
which is invoked everytime after component is rendered. However, the result still remain the same.

So the question is how to make
source
updated whenever
this.state.val
updated?


Updated: Here is the solution I used to solve the prob, using
Rx.Subject


// Component file
constructor() {
super(props)
this.source = new Rx.Subject()
_onChangeHandler(e) {
this.source.onNext(e.target.value)
}
componentDidMount() {
this.source.subscribe(x => console.log(x)) // x is updated
}
render() {
<input type='text' onChange={this._onChangeHandler} />
}
//

Answer

One option could be to use Rx.Observable.ofObjectChanges > cf. https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/ofobjectchanges.md.

However :

  • It uses Object.observe which is not a standard feature, hence will have to be polyfilled in some browsers and is actually being removed from inclusion in ecmascript (cf. http://www.infoq.com/news/2015/11/object-observe-withdrawn). Not the choice for the future, but it is easy to use, so if it is just for your own needs, why not.

Other option is to use a subject in one of the three methods at your disposal according to your use case : shouldComponentUpdate, componentWillUpdate, componentDidUpdate. Cf. https://facebook.github.io/react/docs/component-specs.html for when each function is executed. In one of these methods, you would check if this.state.val has changed, and emits its new value on the subject if it did.

I am not a reactjs specialist, so I guess they might be other options.

Comments