I created an api endpoint with createApi Fn. I need to store response data in localStorage for some time and get it from LS instead of making requests. And when timer is over update data with useQuery.
export const geoApi = createApi({
reducerPath: 'geoApi',
baseQuery: fetchBaseQuery({ baseUrl: GEO_URL }),
endpoints: (builder) => ({
getData: builder.query<any, void>({
query: () => 'geo-data',
}),
}),
});
export const { useGetDataQuery } = geoApi;
I can make it inside component logic (pseudo code):
let geoData = null;
const cachedData = ls.get('GEO_DATA');
if (cachedData && dataIsUpToDate()) {
geoData = cachedData;
} else {
const res = useGetDataQuery();
geoData = res.data;
updateCachedData(geoData);
}
But I would like to do it within redux store logic.
After some time I suggest to use the hook (modify it for your case):
function useCachedData(key, ttl = Infinity, query) {
const [trigger] = query();
const [data, updateData] = useState();
const refreshCache = async () => {
const fetched = await trigger();
localStorage.setItem(key, JSON.stringify({ at: Date.now(), data: fetched.data });
updateData(fetched.data);
}
useEffect(() => {
const cached = localStorage.getItem(key);
let isValid = false;
if (cached) {
const { at, data } = JSON.parse(cached);
if (at + ttl > Date.now()) {
isValid = true;
updateData(data);
}
}
if (!isCached) {
refreshCache();
}
}, []);
return data;
}
And usage with lazy query:
// ...component logic
const geoData = useCachedData('GEO_DATA', 60 * 1000, () => useLazyQuery());