Last active
November 28, 2017 03:11
-
-
Save pluma/fd649dddf55609be10217bf6a161c1e9 to your computer and use it in GitHub Desktop.
Component for handling async data fetching with redux?
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 { Error, ErrorType } from "./Error"; | |
import { Loading } from "./Loading"; | |
import React from "react"; | |
type LoaderProps = { | |
id: string; | |
error?: Object; | |
data: any; | |
isLoading: boolean; | |
expires?: Number; | |
load: Function; | |
renderData: Function; | |
renderError: Function; | |
renderLoading: Function; | |
}; | |
export type RenderProps = { | |
id: string; | |
error?: ErrorType; | |
data: any; | |
isLoading: boolean | null; | |
expires?: Number; | |
refresh: Function; | |
}; | |
export class Loader extends React.Component<LoaderProps> { | |
componentDidMount() { | |
console.log(this.props); | |
if (this.props.isLoading) return; | |
if (Number(this.props.expires) > Date.now()) return; | |
this.props.load(this.props.id); | |
} | |
componentWillReceiveProps(newProps: LoaderProps) { | |
if (newProps.id === this.props.id) return; | |
if (newProps.isLoading) return; | |
if (Number(newProps.expires) > Date.now()) return; | |
newProps.load(newProps.id); | |
} | |
render() { | |
const { | |
load, | |
renderData, | |
renderLoading = () => <Loading />, | |
renderError = ({ error, refresh }: RenderProps) => ( | |
<Error error={error} refresh={refresh} /> | |
), | |
...props | |
} = this.props; | |
const renderChildren = this.props.data | |
? renderData | |
: this.props.isLoading === false ? renderError : renderLoading; | |
return renderChildren({ refresh: () => load(this.props.id), ...props }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The
load
prop updates the app state by settingisLoading
totrue
and clearing theerror
while a side-effect fetches the data. If fetching succeeded,expires
is updated,isLoading
is set tofalse
anddata
is set to the response. If fetching failed,error
is set instead ofdata
. Additionallyexpires
may be set to a closer timestamp than normal to avoid caching temporary errors. TherenderError
method might include a retry button that calls theload
prop. TherenderData
method might include a banner to indicate stale content is being refreshed or that refreshing the content failed (again with aretry
button).