Skip to content

Instantly share code, notes, and snippets.

@OliverJAsh
Last active September 5, 2016 16:08
Show Gist options
  • Save OliverJAsh/c81c12fd4a749251c078c2a8f3fae122 to your computer and use it in GitHub Desktop.
Save OliverJAsh/c81c12fd4a749251c078c2a8f3fae122 to your computer and use it in GitHub Desktop.
Smart component using RxJS Observables
const reportFetchAction = (result?: Result<Report>): ReportFetch => (
{ type: ActionType.ReportFetch, result }
);
// fetchReport = (id: number) => Observable<Result<Report>>
const runFetchReportData = (id: number): Observable<ReportFetch> => {
const report$: Observable<Result<Report>> = fetchReport(id)
return Observable.of(reportFetchAction()).concat(report$.map(reportFetchAction))
}
type State = { reportId: number };
createSmartComponent<State>(
// If lifecycle ends, pending XHRs will be aborted! :-)
(lifecycle$, state) => lifecycle$.flatMap(x => runFetchReportData(state.reportId)),
state => React.createElement('div', {}, [])
)
import {Dispatch} from "../types";
import React = require("react");
import {Subject,Observable,Subscription} from "@reactivex/rxjs";
import {Action} from "../actions";
type DispatchProp = { dispatch: Dispatch };
type ObservableHandler<P> = (
lifecycle: Subject<boolean>,
props: P
) => Observable<Action>
// Smart components receive an observable representing the lifecycle
export default function createSmartComponent<P>(
observableHandler: ObservableHandler<P>,
render: (props: DispatchProp & P) => React.ReactElement<{}>
) {
return class SmartComponent extends React.Component<DispatchProp & P,{}> {
actionsSubscription: Subscription | undefined
lifecycle = new Subject<boolean>()
constructor(props: DispatchProp & P) {
super(props);
this.actionsSubscription = observableHandler(this.lifecycle, props)
.subscribe(this.props.dispatch);
}
render() { return render(this.props) }
componentDidMount() { this.lifecycle.next(true); }
componentWillUnmount() {
this.lifecycle.complete();
this.actionsSubscription && this.actionsSubscription.unsubscribe();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment