Skip to content

Instantly share code, notes, and snippets.

@nicolashery
Last active August 1, 2022 03:36
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nicolashery/6dec8b7b3c9271ff18c9 to your computer and use it in GitHub Desktop.
Save nicolashery/6dec8b7b3c9271ff18c9 to your computer and use it in GitHub Desktop.
Fetching data asynchronously with RxJS and React
import React from 'react';
import _ from 'lodash';
import Rx from 'rx';
import superagent from 'superagent';
let api = {
host: 'http//localhost:3001',
getData(query, cb) {
superagent
.get(this.host + '/data')
.accept('json')
.query(query)
.end((err, resp) => cb(err, resp && resp.body));
},
getData$: Rx.Observable.fromNodeCallback(api.getData.bind(api))
};
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
token: 1,
loading: false,
data: {}
};
}
componentWillMount() {
this.intent$ = new Rx.Subject();
this.intent$
.do(console.log.bind(console, 'clicked'))
.do(() => this.setState({loading: true}))
.throttle(400)
.do(console.log.bind(console, 'requested'))
.flatMapLatest(query => api.getData$(query).map(_.identity))
.do(console.log.bind(console, 'updated'))
.subscribe(data => this.setState({
loading: false,
data: data
}));
}
componentWillUnmount() {
this.intent$.dispose();
}
render() {
return (
<div>
<p>{this.state.loading ? 'loading...' : '.'}</p>
<p>
<button onClick={this.handleClick.bind(this)}>click me</button>
<strong>{` ${this.state.token}`}</strong>
</p>
<pre>{JSON.stringify(this.state.data)}</pre>
</div>
);
}
handleClick() {
this.intent$.onNext({token: this.state.token});
this.setState({token: this.state.token + 1});
}
}
React.render(<App />, document.getElementById('app'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment