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

Support for Suspense in RTK Query #1574

Open
sazzer opened this issue Oct 5, 2021 · 10 comments
Open

Support for Suspense in RTK Query #1574

sazzer opened this issue Oct 5, 2021 · 10 comments
Labels
enhancement New feature or request rtk-query

Comments

@sazzer
Copy link

sazzer commented Oct 5, 2021

Redux Toolkit and RTK Query are awesome, and have really made it easier to get things working quickly and well.

What would be really good though is to have support for the React Suspense API, so that we can render a fallback component whilst data is loading without needing to handle it in-component with the isLoading flag.

It's not a huge deal, but it just makes things that little bit neater to have a wrapper around the component that handles this instead.

Cheers

@phryneas
Copy link
Member

phryneas commented Oct 5, 2021

RTK 1.7 will have the necessary internal changes for that. (see #1277) After that we'll probably release an external package marked as "unstable" with a module for suspense hooks.

@sazzer
Copy link
Author

sazzer commented Oct 5, 2021

Awesome :)

Is there anything that documents upcoming changes? I did a search for "Suspense" in the issues but nothing that looked relevant came up.

@phryneas
Copy link
Member

phryneas commented Oct 5, 2021

Not really, but you will need the new api.getRunningQueryPromise function as a base foundation.

@AndrewCraswell
Copy link
Contributor

Looks like 1.7 released last month, and the suspense is killing me ;)

@phryneas
Copy link
Member

phryneas commented Jan 9, 2022

All the building blocks for it are there now, so you could build your own hooks or RTK Query plugin for it at this time.

But I don't have the capacity to build anything at the moment. If you want this functionality in the near future, it probably has to come from the community.

@laurencefass
Copy link

Moving loading states out of components into Suspense looks like the way forward and there seems to be a lot of work going in other frameworks to accomodate. Will there be any first-class Suspense support in RTK Query in the future?

@phryneas
Copy link
Member

@laurencefass yes, for example in the PR #2245 directly above your answer. The point is though, that Suspense has not officially been declared as "ready for use with client-side libraries" by the React team yet, but only as "ready for use if you use an opinionated framework like next if that supports it".

@luke10x
Copy link

luke10x commented Jun 16, 2022

I ended up writing my own quick-and-dirty hook using api.getRunningQueryPromise as @phryneas mentioned in previous comments:

// Simplified version of QueryActionCreatorResult
interface WrappedData<T extends unknown> {
  data: T
}

export const useRtkQueryResource = <T extends unknown>(api: unknown, endpointName: string): never | (() => T) => {
  // @ts-ignore
  const apiEndpointQuery = api.endpoints[endpointName]
  // @ts-ignore
  const useEndpointQuery = apiEndpointQuery?.useQuery
  
  const { data } = useEndpointQuery(null) as WrappedData<T>

  // @ts-ignore
  let promise = api
    // @ts-ignore
    .util
    .getRunningOperationPromise(endpointName, null) as PromiseLike<WrappedData<T>>|undefined

  // Promise is undefined when data is there cached locally already,
  // in this case let's have a promise resolved with the locally cached data
  if (promise === undefined) {
    promise = new Promise(
      (resolve, reject)=> {
        if (data !== undefined) {
          resolve({ data })
        } else {
          reject("Cannot get RTK Query promise and there is no data loaded yet")
        }
      }
    )
  }
  
  let status = 'pending'
  let response: T

  promise.then(
    (res: WrappedData<T>) => {
      status = 'success'
      response = res.data
    },
    (err) => {
      status = 'error'
      response = err
    },
  )

  return () => {
    switch (status) {
      case 'pending':
        throw promise
      case 'error':
        throw response
      default:
        return response
    }
  }
}

@markerikson
Copy link
Collaborator

markerikson commented Jun 22, 2022

For the record, I just built a proof of concept "Suspense Cache" using RTK Query. Not final yet, but you can see the PR here:

replayio/devtools#7205

This lets you do:

function MyComponent() {
  const data = getDataFromSuspenseCache()
  
  // render here
}

while encapsulating the whole "throw a promise or return the data" thing.

(fixed the wrong PR link)

@markerikson
Copy link
Collaborator

markerikson commented Dec 12, 2022

Relevant thoughts over in the React Query repo:

TanStack/query#4623

Also probably outdated discussion on Twitter:

https://twitter.com/arnbzn/status/1435529763893006336

@markerikson markerikson added the enhancement New feature or request label Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request rtk-query
Projects
None yet
Development

No branches or pull requests

6 participants