Skip to content

Instantly share code, notes, and snippets.

@Rafe
Created January 12, 2021 13:58
Show Gist options
  • Save Rafe/3b0e152cd6587f8c0366f8e00e6acb7c to your computer and use it in GitHub Desktop.
Save Rafe/3b0e152cd6587f8c0366f8e00e6acb7c to your computer and use it in GitHub Desktop.

Revisions

  1. Rafe created this gist Jan 12, 2021.
    50 changes: 50 additions & 0 deletions SuspenseFetch.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    const Unitialized = -1;
    const Pending = 0;
    const Resolved = 1;
    const Rejected = 2;

    function suspenseFetch(url) {
    const payload = {
    _status: Unitialized,
    _result: () => fetch(url)
    }

    return () => {
    if (payload._status === Uninitialized) {
    const promise = payload._result()
    payload._status = Pending
    payload._result = promise

    promise.then((res) => {
    if (payload._status === Pending) {
    payload._status = Resolved
    payload._result = res
    }
    }, (err) => {
    if (payload._status === Pending) {
    payload._status = Rejected
    payload._result = err
    }
    })
    } else if (payload._status === Resolved) {
    return payload._result
    } else {
    throw payload._result
    }
    }
    }

    // in app
    const fetchUser = suspenseFetch(`/users/1`)

    const User = () => {
    const user = fetchUser()

    return <div>{user.name}</div>
    }

    const App = () => (
    <Suspense fallback={<h1>Loading user...</h1>}>
    <User>
    </Suspense>
    )