Reputation: 31
I am building a small app that tracks progress of mountain summit peak lists for hikers. I am using RTK Query for the first time for the majority of state management. I need to create a piece of derived state, a "list counts" object, which contains key value pairs of peak list IDs and the number of peaks completed on that list. Data returned from two RTK Query hook calls is needed to calculate it and this derived data is needed in multiple components:
const listCounts = {
nh4k: 6,
ne100: 5,
usHigh: 3,
// more data
}
I have two query hooks from RTK Query which work to fetch the necessary data from the backend. My current working solution is a custom hook which calls each hook generated by RTK Query and returns listCounts:
const useListCounts = () => {
const { data: peakLists } = useGetPeakListsQuery();
const { data: logEntries } = useGetLogEntriesQuery();
// logic to create listCounts object
return listCounts;
}
Is this appropriate use of a custom hook? I don't have a ton of experience using custom hooks but most other examples I have seen return some value from a built in React hook such as useState, useReducer etc.
Another solution I have considered is to create a separate function, call each RTK query hook in the component directly and then pass the data to the function in the component:
// in util function file:
const calculateListCounts = (peakLists, logEntries) => {
// logic to create listCounts object
return listCounts;
}
// In component file:
import { calculateListCounts } from "..."
const MyComponent = () => {
const { data: peakLists } = useGetPeakListsQuery();
const { data: logEntries } = useGetLogEntriesQuery();
const listCounts = calculateListCounts(peakLists, logEntries);
// return JSX
}
Is there any reason to prefer either option above, or is there some way to access RTK query cache outside of a React component or custom hook so that I can calculate and return listCounts with a single function call?
I have several other similar situations where some piece of derived state calculated using data returned from RTK Query hooks is needed across multiple components and want to make sure I'm following the correct pattern.
Upvotes: 3
Views: 760
Reputation: 401
I'm no expert either, but I believe using a custom hook is better than a plain function. The advantages I see are:
isLoading
, isFetching
and any other metadata of the queries you need,The only suggestion I have is to respect the query interface as much as possible, so your components can use it as any other query from your server:
const useListCountsQuery = () => {
const { data: peakLists, isLoading: peakLoading } = useGetPeakListsQuery();
const { data: logEntries, isLoading: logLoading } = useGetLogEntriesQuery();
// We use useMemo hook to avoid recalculating the derived state except the original data changes
const listCounts = useMemo(
() => // your logic,
[peakLists, logEntries]
)
// We mimic RTK query interface so we can use this derived data as any other query
return { data: listCounts, isLoading: peakLoading || logLoading }
}
Upvotes: 0