Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suspense API #11

Open
thomasdashney opened this issue Mar 1, 2020 · 1 comment
Open

Suspense API #11

thomasdashney opened this issue Mar 1, 2020 · 1 comment
Assignees
Projects

Comments

@thomasdashney
Copy link
Contributor

Since this data-fetching library has a built-in cache, we are well-positioned to implement a suspense API in addition to the useApiQuery state-based API.

The API should support both "fetch as you render" and "fetch before render".

@thomasdashney
Copy link
Contributor Author

thomasdashney commented Mar 6, 2020

@azmenak I gave this some thought last night and used rest-hooks for some ideas. Still some open questions and parts which wouldn't necessarily be trivial to implement (would require some additions to Api).

Using a cached API response:

const [users] = useApiData(UserEndpoints.list())

This hook would read the data from the cache directly, and does one of the following:

  • If the data is not yet in the cache, and there is not a request in-flight, trigger a fetch and throw a promise that resolves when the fetch resolves.
  • If the data is not yet in the cache, and there is a request in-flight, throw a promise which resolves as soon as there is data available in the cache.
  • If the data is in the cache, return the data.

Other things to consider:

  • It should listen for updates to the cached data (via other calls) and always return the latest value
  • We would likely want to re-validate the cache (by re-fetching) after the cached value is considered stale (possibly some duration). We could potentially just use fetchPolicy similarly to useApiQuery
  • If the promise thrown by the hook (due to the above cases) rejects, suspense should automatically throw it to bubble up to an ErrorBoundary. However, we should consider a good pattern for error-handling re-validating fetches in the future which fail.
  • I thought it would be useful for this to be a tuple which returns actions as the second value.. for example, we might want to revalidate() by fetching a fresh version in the background, invalidate() to clear the cache and fetch a new version, etc.

Pre-fetching data imperatively:

const prefetch = useApiPrefetcher()

return (
  <button type='button' onClick={() => {
    prefetch(UserEndpoints.list())
  }}>
    Load user
  </button>
)
  • Just makes a fresh fetch via fetchPolicy: fetch-first and stores the response in the cache.
  • Not sure how we would handle error (maybe Api#onError to start)

Pre-fetching data as it renders (ie useEffect):

useApiPrefetch(UserEndpoints.list())
  • Similar to useApiPrefetcher but automatically fetches via useEffect
  • Not sure how we would handle error (maybe Api#onError to start)

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

No branches or pull requests

2 participants