Skip to content

Instantly share code, notes, and snippets.

@pluma
Last active November 28, 2017 03:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pluma/fd649dddf55609be10217bf6a161c1e9 to your computer and use it in GitHub Desktop.
Save pluma/fd649dddf55609be10217bf6a161c1e9 to your computer and use it in GitHub Desktop.
Component for handling async data fetching with redux?
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 });
}
}
@pluma
Copy link
Author

pluma commented Nov 27, 2017

The load prop updates the app state by setting isLoading to true and clearing the error while a side-effect fetches the data. If fetching succeeded, expires is updated, isLoading is set to false and data is set to the response. If fetching failed, error is set instead of data. Additionally expires may be set to a closer timestamp than normal to avoid caching temporary errors. The renderError method might include a retry button that calls the load prop. The renderData method might include a banner to indicate stale content is being refreshed or that refreshing the content failed (again with a retry button).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment