-
Hello everyone, I'm working on a React project using React Query for data fetching and caching. My application fetches weather data from an API and then processes this data for display. Here's a simplified version of my setup: export async function fetchWeatherData({
provider,
lat,
lon,
region,
processor ,
units,
language
}:FetchWeatherProp) {
if (lat && lon && region) {
try {
const data = await processor.groupFetch({
provider,
lat,
lon,
region,
});
const processedData = processor.convertToAppWeather(data, units, language);
return processedData
} catch (e) {
throw e;
}
}
}
export const useGlobalDataFetch = (area: AreaStoreProps) => {
const { provider, processor, adapterModel } = useWeatherProcessor(area);
const lat = area?.coord?.lat;
const lon = area?.coord?.lon;
const region = area?.region;
const {language} = useLanguageStore()
const { rainSnowUnit, timeFormat, temperatureUnit } = useUnitStore();
const units = { rainSnowUnit, timeFormat, temperatureUnit};
const isEnabled = !!(lat && lon &®ion && units );
const {data:homeData, error, isLoading, refetch } = useQuery<HomeWeather>({
queryKey: ['globalData', { provider, lat, lon, region, language, units }],
queryFn: () =>
lat !== undefined && lon !== undefined && region !== undefined
? fetchWeatherData({ provider, lat, lon, region, processor, language, units })
: Promise.reject("Missing lat, lon, or region"),
enabled: isEnabled,
});
return {
provider,
error,
isLoading,
refetch,
homeData,
processor,
adapterModel,
...units,
language,
};
}; The above works very well , very smooth , but it cause unnecessary refetch, I considered using useMemo to optimize processing but encountered performance issues on specific pages, likely due to the complexity of the processing function. export async function fetchWeatherData({
provider,
lat,
lon,
region,
processor ,
}:FetchWeatherProp) {
if (lat && lon && region) {
try {
const data = await processor.groupFetch({
provider,
lat,
lon,
region,
});
return data
} catch (e) {
throw e;
}
}
}
export const useGlobalDataFetch = (area: AreaStoreProps) => {
const { provider, processor, adapterModel } = useWeatherProcessor(area);
const lat = area?.coord?.lat;
const lon = area?.coord?.lon;
const region = area?.region;
const {language} = useLanguageStore()
const { rainSnowUnit, timeFormat, temperatureUnit } = useUnitStore();
const units = { rainSnowUnit, timeFormat, temperatureUnit};
const isEnabled = !!(lat && lon &®ion && units );
const {data:rawData, error, isLoading, refetch } = useQuery({
queryKey: ['globalData', { provider, lat, lon, region}],
queryFn: () =>
lat !== undefined && lon !== undefined && region !== undefined
? fetchWeatherData({ provider, lat, lon, region, processor})
: Promise.reject("Missing lat, lon, or region"),
enabled: isEnabled
});
const homeData = useMemo(() => {
if (!rawData) return null;
return processor.convertToAppWeather(rawData, units, language);
}, [rawData, rainSnowUnit, timeFormat, temperatureUnit, language]);
return {
provider,
error,
isLoading,
refetch,
homeData,
processor,
adapterModel,
...units,
language,
};
}; I'm looking for a strategy to cache the processed data alongside the raw data cache provided by React Query, ensuring that: The processed data is only recalculated when necessary (e.g., when the raw data or relevant query parameters change). Thank you in advance for your help and suggestions! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
use https://tkdodo.eu/blog/react-query-data-transformations#3-using-the-select-option |
Beta Was this translation helpful? Give feedback.
use
select
, and wrap it inuseCallback
:https://tkdodo.eu/blog/react-query-data-transformations#3-using-the-select-option