Futures: Making queries composable (mapping, combining) #8660
Unanswered
GiacoCorsiglia
asked this question in
Ideas
Replies: 1 comment
-
|
for if you want to build this, I think you can do it in user-land, but I don’t think I want to introduce those concepts into react-query itself. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
First: fantastic library with super thorough documentation, thank you :)
I'm curious if thought has been given to formalizing the
UseQueryResultas The Way to represent async state in React/rendering libraries in general. For now, let's call this type aFutureand explore some (I think) useful things we can do. I've used something like this successfully in two separate professional projects.The minimal definition of a
Futuremight look something like this:This is compatible with both TanStack Query and also SWR. Of course, the real version would need to give thought to the other properties on
UseQueryResult(likely,UseQueryResultextendsFuturewith extra properties). It might also be nice to make this a discriminated union somehow.There are (at least) 3 useful things we can do with this.
mapFuture: transforming query resultsmapFutureis likePromise#thenfor aFuture. A simplistic version looks like this:This lets you transform the result of your query on the client while preserving the loading state. For example:
Sure, you can totally do this in all the components that call
useProducts, once they have checked ifproducts.datahas loaded, but I would rather encapsulate that in theuseProductshook.mapFuturecan be extended to allow transforming theerror, too, similar to howPromise#thensupports a second argument that works likePromise#catch.I think
mapFuturemakes theFuturetype a "Functor".Maybe
mapFutureis implemented as a method onFutureinstead (i.e.,products.map()instead ofmapFuture(products)).combineFutures: LikePromise.allfor Futures.You can merge the results of multiple queries in arbitrary ways using
combineFutures.This is similar to, but not the same as,
useQueries(), which supports acombineargument. The benefit of having a separate function is that things compose more cleanly. For example,I'm sure there is a functional programming term for
combineFutures.Creating a
FuturewithoutuseQuery().Occasionally, there are scenarios where you have async state but don't want or need
useQuery(). This is why it's useful to have a standaloneFutureconcept—outside ofUseQueryResult. For example:You can compose this with other Futures (e.g., using
combineFutures), some of which may have come fromuseQuery(). Also, if you have implemented, for example, a component that shows a loading state when waiting for the result of auseQuery(), you can use that same component to wait for the heavy library to load—because that component expects aFuture.I would love to hear others' thoughts on this idea.
Beta Was this translation helpful? Give feedback.
All reactions