rony l
rony l

Reputation: 6012

Best practices to imperatively invoke GET requests (with caching) in react-query?

I am building a React component for typeahead address search, which uses a cloud service to fetch potential address matches. When a user selects an address from the dropdown, I need to make another network call to retrieve additional details (like coordinates) for that address. After fetching these details, I want to trigger an onSelect callback prop to notify the parent component.

Requirements:

  1. Invoke onSelect exactly once for each user selection.
  2. Cache the results of the network calls, as there's no need to invalidate the cache.

Options Considered:

  1. Using await retrieve() in Event Handler: This approach doesn't offer caching. I would need to manage the cache manually, perhaps using useState. It also doesn't handle scenarios like component unmounting during an ongoing request.

  2. Using useQuery from TanStack: I considered using its onSuccess callback to trigger onSelect. However, onSuccess may not fire if the data is already cached. Additionally, ensuring that the query runs exactly once seems challenging. I might have to use refetch(), which feels like overkill.

  3. Using queryClient.fetchQuery: This could be an alternative to useQuery, with a staleTime set to Infinity to ensure caching.

Question:

What is the most effective and readable pattern to achieve these requirements? I'm looking for a solution that is easy to implement, easy to read, and adheres to the specified requirements.

Upvotes: 0

Views: 686

Answers (1)

TkDodo
TkDodo

Reputation: 28833

It's number 3: queryClient.fetchQuery with a staleTime set to Infinity. Alternatively, you can use queryClient.ensureQueryData, which will only fetch if there isn't data in the cache.

You can await calls to that method and then invoke the onSuccess callback.

Note that without useQuery, you have no observer, so your Query is eligible for garbage collection, which means data will be removed after the default of 5 minutes. You can set a higher cacheTime (v4 - it's gcTime in v5).

Upvotes: 1

Related Questions