Skip to content

Instantly share code, notes, and snippets.

@busypeoples
Created November 4, 2017 13:09
Show Gist options
  • Save busypeoples/8c033285fe8714ec4ecba9a7b222abb8 to your computer and use it in GitHub Desktop.
Save busypeoples/8c033285fe8714ec4ecba9a7b222abb8 to your computer and use it in GitHub Desktop.
Loader Implementation
import React from 'react';
import daggy from 'daggy';
// Inspired by:
// "Slaying a UI Antipattern in Fantasyland" @thinkfunctional
// https://medium.com/javascript-inside/slaying-a-ui-antipattern-in-fantasyland-907cbc322d2a
// "Use a Render Prop!"
// https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce @mjackson
// Loader in ReasonML @ryyppy
// https://github.com/ryyppy/reason-lnd/blob/master/frontend/src/loader.re
const RemoteData = daggy.taggedSum('RemoteData', {
NotAsked: [],
Loading: [],
Failure: ['error'],
Success: ['data']
});
class Loader extends React.Component {
state = { items: RemoteData.NotAsked };
loadData = () => {
const { url, fetch } = this.props;
this.setState(state => ({ items: RemoteData.Loading }));
const getItems = fetch();
getItems.then(
data => {
this.setState(state => ({
items: RemoteData.Success(data)
}));
},
error => {
this.setState(state => ({
items: RemoteData.Failure(error)
}));
}
);
};
getView = items => {
const {
renderNotAsked,
renderLoading,
renderError,
renderSuccess
} = this.props;
return items.cata({
NotAsked: () => renderNotAsked(),
Loading: () => renderLoading(),
Failure: error => renderError(error),
Success: data => renderSuccess(data)
});
};
render() {
const { items } = this.state;
const { children } = this.props;
const View = this.getView(items);
return children(View, this.loadData);
}
}
export default Loader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment