Last active
September 5, 2016 16:08
-
-
Save OliverJAsh/c81c12fd4a749251c078c2a8f3fae122 to your computer and use it in GitHub Desktop.
Smart component using RxJS Observables
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
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', {}, []) | |
) |
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 {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