5

I want to do some side effects like setState and update context after the data is fetched. However, the onSuccess will not be executed when the data is in cache. Also useEffect doesn't work because if the data is cached, it doesn't change from undefined to the real data. Therefore it doesn't get trigger either. What's the best way of doing this? Thanks

XINDI LI
  • 625
  • 2
  • 7
  • 16
  • what's your use-case please? if `data` didn't change or the fetch function is not even invoked, why do you need to "set some state" ? – TkDodo Jan 28 '21 at 14:55
  • Actually I figured it out. My usecase is to extract some values from the data returned from useQuery and set a new state on those. I ended up with useEffect with a if(data) in it – XINDI LI Jan 28 '21 at 15:18

1 Answers1

3

My usecase is to extract some values from the data returned from useQuery and set a new state on those.

usually, they’re shouldn’t be a need to be a need to copy state from react-query into local state. This will just lead to duplication of the source of truth. It is best to keep them separated, so that you can also profit from background updates.

If you want to transform the data or subscribe to parts of the data, use the select option of useQuery:

const { data } = useQuery(key, fn, { select: data => data.map(...) })

Alternatively, you can compute some new data depending on the returned data with useMemo, e.g.:

const { data } = useQuery(...)

const articles = useMemo(() => data?.map(...), [data])
// work with articles from here on

You can also put that nicely in a custom hook.

TkDodo
  • 20,449
  • 3
  • 50
  • 65
  • Thank you for your response. What if I want to do some other side effects like set context? – XINDI LI Jan 28 '21 at 18:07
  • background updates is a good point and I don't think useEffect will be triggered for that – XINDI LI Jan 28 '21 at 18:09
  • Why would you put the data into context? You van just grab it everywhere with `useQuery` ‍♂️ – TkDodo Jan 28 '21 at 20:47
  • You mean use the same useQuery to fetch data again from cache? – XINDI LI Jan 28 '21 at 21:25
  • What if the data transformation is expensive? I'd rather store the extracted data in the context than compute it every time I need it on the fly – XINDI LI Jan 28 '21 at 21:29
  • Even if you can get the data from the cache, it will still do a refetch on the background. Although it doesn't show the loading, it's still an overhead – XINDI LI Jan 28 '21 at 21:32
  • background refetches can be customized by setting `staleTime`. `useMemo` and `select` only run when the data is really different due to the "structural sharing" feature of react-query. It does sound a bit like premature optimizations to me. Do you have a perf issue you are trying to solve? – TkDodo Jan 29 '21 at 09:13
  • 1
    Not really. If useMemo can be triggered so can useEffect. So I guess if I have to some side effects, useEffect is the way to go – XINDI LI Jan 29 '21 at 15:06