blog/react-query-data-transformations #57
Replies: 53 comments 51 replies
-
The select is nifty! Haven't tried out v3 yet, looking forward to trying out. As a slight variation on 1 I've sometimes put both the untouched server data and the derived data into the cache, something like
|
Beta Was this translation helpful? Give feedback.
-
That looks good if you need both the raw data and the derived data in the cache 👍 |
Beta Was this translation helpful? Give feedback.
-
Wow!! That's really good.👍 Thanks Dominik!🙏 |
Beta Was this translation helpful? Give feedback.
-
Hello, thanks for sharing these useful insights! What different does it make if the select function is an inline one vs a stable function reference? |
Beta Was this translation helpful? Give feedback.
-
if it's an inline function, it will be executed on every render, even if neither I suggest to just start with an inline function, and if you measure some slowness, you can improve it. It's likely perfectly fine to inline it :) |
Beta Was this translation helpful? Give feedback.
-
Thank you for this great article series! Correct me if I'm wrong, but since the select option runs once per component instance, what would you recommend if you only want a data transformation to run once for multiple component instances? For example, let's say we have a useQuery call with a select option that runs an expensive computation wrapped in a custom hook and that custom hook is called by many components throughout an application. Is the only option then to move the data transformation to the queryFn and have it run once per fetch? |
Beta Was this translation helpful? Give feedback.
-
If the select function is stable, it will only execute when |
Beta Was this translation helpful? Give feedback.
-
Thanks for the clarification! I made a codesandbox to better illustrate the example I'm talking about where the select function is called once per component that's consuming the custom hook with the useQuery call, despite having a stable function reference (I think). What am I missing? |
Beta Was this translation helpful? Give feedback.
-
You’re right. select is a per-observer option, so every usage will have it's own select memory, which means it has to at least run once per observer. It seems that indeed the only other option is to move it into the queryFn. I don’t think there is a way to transform there only once, but something like memoize-one could help. |
Beta Was this translation helpful? Give feedback.
-
I'm having problems with export function useConversation(to: string) {
const user = useUser();
return useInfiniteQuery<MessageListResponse>(
[QueryKeys.MessageList, { userId: user?.guid, to }],
({ pageParam = 1 }) => {
return $axios.$post(`/api/${QueryKeys.MessageList}`, {
guid: user.value?.guid,
to: to,
offset: pageParam
});
},
{
getNextPageParam,
enabled: !!to,
select: (data) => { // type error
const pages = data.pages.map((page) => {
return transformList(page.payload.list);
});
return {
...data,
pages,
};
},
}
);
} Without the undefined | InfiniteData<MessageListResponse> But with the |
Beta Was this translation helpful? Give feedback.
-
@wobsoriano I can take a closer look at it if you can create a minimal example in codesandbox |
Beta Was this translation helpful? Give feedback.
-
Here you go https://codesandbox.io/s/use-query-infinite-ts-583sp |
Beta Was this translation helpful? Give feedback.
-
Ah yes, you cannot use |
Beta Was this translation helpful? Give feedback.
-
Ah, that makes sense. I updated my example and used your 2nd option instead. Works fine. |
Beta Was this translation helpful? Give feedback.
-
Thank you so much for this guide! I find myself keep coming back here as a reference. |
Beta Was this translation helpful? Give feedback.
-
Great job on these series of posts, thanks! I've been using the second option in one of my projects and wondered if this is still relevant in v4? The reason being is that using the spread operator on To give some context, I'm trying to use local state as a fallback if the server state isn't available (recommended here). Perhaps a selector is the way forward, although it doesn't feel 'right' to closure over data in |
Beta Was this translation helpful? Give feedback.
-
Awesome article as usual 🔥 so basically do we create a new query hook for each selected slice of data? |
Beta Was this translation helpful? Give feedback.
-
Thank you for such informative article. I had a question regarding it. I am trying to implement the select in my TypeScript project. I feel like the return type of the select can be very generic. What would be the suggested way of approaching this? |
Beta Was this translation helpful? Give feedback.
-
Hi, thank you for introducing great features of React Query with this great article. I have one question regarding the last example code. thanks in advance! |
Beta Was this translation helpful? Give feedback.
-
When using the select function to filter data, is there a better way to get the original data than returning it back in a object along with the filtered data in the select function? |
Beta Was this translation helpful? Give feedback.
-
Thank you for the amazing write up, "data inside the queryInfo will be referentially stable unless something really changed" does that changes every time the function passed to the useQuery get's invoked |
Beta Was this translation helpful? Give feedback.
-
@TkDodo, this looks great. I'm curious about typescript implementation. When I try something like:
I keep getting typescript errors on the useTodo-like function:
Have I got something incorrectly typed? Or is this expected? Also -- when I console.log in fetchSingleTodo, it logs multiple times for the same ID and data. Is it not cached? |
Beta Was this translation helpful? Give feedback.
-
Hi TkDodo, We heavly depend on So for example if we mapping 1000 objects inside (select) prop then reusing this hooks in 10 different places causes mapping 10 000 objects for the scope of whole application. Does it mean that we have to use different state manager for this ? Is there any possibility to make sure that select is executed once for the scope of whole app ? Thanks I was thinking maybe if would be good idea to put mapped data into cache instead of select but is it only solution? |
Beta Was this translation helpful? Give feedback.
-
Hi TkDodo,
|
Beta Was this translation helpful? Give feedback.
-
Hi community and @TkDodo, I've been using selector to transform my data, it is great, however, I was wondering how should I test it? In my test I have this
So my I do not want to use the transformed data as my Mock because that won't test the transform function. what I did was extract the
and finally in my test imported the transform function
in that way, the test is also testing the transform function, but is this the correct approach? is there other better? |
Beta Was this translation helpful? Give feedback.
-
Hey TKDodo! Awesome blog post! I'm wondering if the select fn depends on other dynamic data to have its result enriched, having that dynamic data as a dependency of the select wrapped in a useCallback, will make it rerun once the dynamic data changes without triggering a refetch? is it a good practice? Thank you |
Beta Was this translation helpful? Give feedback.
-
TkDodo thanks for making this blog, it's been a great resource for learning! I've encountered an issue I can't figure out, I hope the community here can show me where I'm wrong. Thanks! export const useDataQuery = () => {
return useQuery({
queryKey: ["/data"],
queryFn: getData,
select: useCallback((data: DataProps[]): Map<string, DataProps[]> => {
const dataMap = new Map<string, dataProps[]>()
data?.forEach((element) => {
const dataDate = getDataDate(new Date(element.time))
if (!dataMap.has(dataDate)) {
dataMap.set(dataDate, [])
}
const dataOnDate = dataMap.get(dataDate)
dataMap.push(element)
})
console.log("new DataMap")
return dataMap
}, []),
})
}
// component.js
export const ListData = () => {
const { data: dataMap } = useDataQuery()
... component logic ... |
Beta Was this translation helpful? Give feedback.
-
Continuing to come back to various articles in your awesome blog - thanks again for these resources. When implementing
we are using v5 - does passing the select function to the query key properly cache each situation? |
Beta Was this translation helpful? Give feedback.
-
I want to use this select option in an enabled query & I'm facing type issue with select option & can't get my head around it
& I want to possibly use it like this
and this is the type of function |
Beta Was this translation helpful? Give feedback.
-
absolutely 🔥 blog post.. just loving it 👍🏽 |
Beta Was this translation helpful? Give feedback.
-
React Query Data Transformations | TkDodo's blog
Learn the possibilities to perform the quite common and important task of transforming your data with react-query
https://tkdodo.eu/blog/react-query-data-transformations
Beta Was this translation helpful? Give feedback.
All reactions