Skip to content

Instantly share code, notes, and snippets.

@alexeyraspopov
Last active December 6, 2019 23:23
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 alexeyraspopov/adf20e4107216cf166b348c7b85eae3a to your computer and use it in GitHub Desktop.
Save alexeyraspopov/adf20e4107216cf166b348c7b85eae3a to your computer and use it in GitHub Desktop.
export function useResource(fn, input) {
return useMemo(() => {
let resource = { type: 'Pending', value: null };
resource.value = Promise.resolve(fn(...input))
.then(result => Object.assign(resource, { type: 'Resolved', value: result }))
.catch(error => Object.assign(resource, { type: 'Rejected', value: error }));
return resource;
}, input);
}
export function useValueOf(resource) {
return useMemo(() => {
switch (resource.type) {
case 'Pending':
let suspender = resource.value;
throw suspender;
case 'Rejected':
let error = resource.value;
throw error;
case 'Resolved':
default:
let result = resource.value;
return result;
}
}, [resource]);
}
async function fetchUser(id) { return fetch(); }
function Parent() {
let resource = useResource(fetchUser, [id]);
return (
<Suspense fallback={<span>loading…</span>}>
<Child resource={resource} />
</Suspense>
)
}
function Child({ resource }) {
let data = useValueOf(resource);
return <JSX />;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment