What's the best approach to transform data and then subscribe to it? #5094
-
Using v3 and given the code below, the Seems like perhaps transforming in the const useCustomHook = () => {
const { data } = useQuery(
['cool-data'],
() => fetchCoolData(),
{
notifyOnChangeProps: 'tracked',
select: expensiveTransform,
},
)
} // A.js
useCustomHook()
/// B.JS
useCustomHook()
/// C.JS
useCustomHook()
// If this hook above is used at different times but on the same route, they will all run the expensive select.
If I do transform within the const fetchCoolData = async () => {
const res = await fetch(`https://cool...etc`)
return res.json()
.then(expensiveTransform)
.catch(logError)
} |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 9 replies
-
Hi 👋 Yes, whatever operation(s) you perform in the query function will run every time the data is fetched (i.e the query function runs). You might want to consider memoising the Please see: https://tkdodo.eu/blog/react-query-data-transformations 🙂 |
Beta Was this translation helpful? Give feedback.
-
so, in summary:
The solution would be to introduce another caching that memoizes the transformation outside of react by its input so that you use it for select, but run it only once.
👍 |
Beta Was this translation helpful? Give feedback.
-
I came across this question because I have the same problem as the OP. Thing is, in my scenario, the accepted solution doesnt work because I need data from another useQuery hook for the selector, so the selector needs to be inside the React Component. Its a shame that the select doesnt cache the result, as this makes it almost mandatory to use redux. In our app its not a big deal as we already have redux, but we were trying to eliminate more client state :) |
Beta Was this translation helpful? Give feedback.
-
Joining the conversation here as I have a pretty similar need but trying to mix redux data with RQ data in a unique efficient selector. I can move it to a different discussion if you prefer. I read many issues and discussions related to this topic (also a blog post which mentions the same need) but still could not find a clean way to achieve it. The problem The code Thanks! |
Beta Was this translation helpful? Give feedback.
so, in summary:
queryFn
- it will be executed on every fetch, even if data didn't change, because it happens before structural sharingselect
- it will run once for every subscriberThe solution would be to introduce another caching that memoizes the transformation outside of react by its input so that you use it for select, but run it only once.
reselect
works well for that, and your shown code is exactly how I would do it / have done it in the past:👍