2
votes

I'm using react-query library to fetch data from API, and I wrote code to make optimistic updates (because API is slow).

So, for example, I'm making requests with useQuery:

const { data } = useQuery('posts', loadPostsFunction)

And in the other place, I make updates in the cache, that code is more complicated so I will omit actual code, here is simplified:

const updatingId = 123
const newTitle = 'new title'

queryClient.setQueryData<Post[] | undefined>('posts', (data) =>
  data?.map(post =>
    post.id === updatingId
      ? { ...data, title: newTitle }
      : post
  )
)

The problem is that I have a lot of different queries with different resources, and I want to map somehow the cache key with the type of data which is stored under the key.

I'd like to have something similar to having a store with defined cache keys and cache types:

const { data } = useQuery(store.postsKey, loadPostsFunction)

And to make updates like:

store.updatePost(post.id, { title: 'new title' })

Why? Because updating cache is a single untyped piece in the code that already brought some bugs.

When making a query I can't be sure that under the key 'post' there is definitely an array of the exactly expected type, what if my data loading function will return something other, or what if I use useInfiniteQuery to get paginated data, then the type will differ.

And same for updating the cache, now I can't be sure that under the specific key there is exactly what I'm expecting.

I began to write a solution, it appeared to be far from elegant, so I decided to ask if someone already solved this, what if there is a ready library or code example.

1

1 Answers

0
votes

I think the only way to do it as far as I know is a custom wrapper like you already started:

const updatePost = (post: Post) => queryClient.setQueryData<Post>(store.postsKey, post)

I started to create a "typed query cache" some time ago, but never went really far with it. It takes a schema as input and gives you a typed version of the queryCache, so that setQueryData and getQueryData are fully typed. This was on v2, but the principle is still the same if you want to take a look: https://gist.github.com/TkDodo/74051d3224358b8a7f2407630885cbda