Skip to content

Instantly share code, notes, and snippets.

@edewit
Last active January 6, 2020 09:26
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 edewit/46b9258bf57665ab676723f72b03bd75 to your computer and use it in GitHub Desktop.
Save edewit/46b9258bf57665ab676723f72b03bd75 to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from 'react';
export default function DataLoader(props) {
const [data, setData] = useState(undefined);
const [error, setError] = useState();
useEffect(() => {
setData(undefined);
const loadData = async () => {
try {
const result = await props.loader();
setData({ result });
} catch (e) {
setError(e);
}
};
loadData();
}, [props]);
if (!!data) {
if (props.children instanceof Function) {
return props.children(data.result);
}
return props.children;
}
return (<Loader error={error} aria-label="Loading data" />);
}
export function Loader(props) {
return (
<div>
{!props || (!props.error && (
<h2>loading...</h2>
))}
{props && props.error &&
<h5>Error</h5>
<p>{props.error}</p>
}
</div>
);
}
function ListLoader(props) {
const loader = async () => {
return await fetch(props.url).then(res => res.json());
};
return (
<DataLoader loader={loader}>
{props.children}
</DataLoader>
);
}
export function FruitLoader(props) {
return ListLoader({...props, url: '/api/fruits/'})
}
export default function Fruit() {
return (
<div>
<h3>Fruit List</h3>
<div className="row">
<div className="col-4">Name</div>
<div className="col-8">Description</div>
</div>
<FruitLoader>
{fetchedFruits => (
fetchedFruits.map((fruit, i) => (
<div className="row" key={i}>
<div className="col-4">{fruit.name}</div>
<div className="col-8">{fruit.description}</div>
</div>
))
)}
</FruitLoader>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment