'Cache data from api with reactjs
i just started learning react recently and i am facing a problem with caching data. this my idea, i don't know if it's the correct way. Sorry cause bad english and thanks for helps.
I wrote a hook that allows cache data after calling the api with web url as key, if the web call that api again they will return cached data instead of calling that api again.
I used session storage because it doesn't share data between browser tabs, the problem is that I thought it would lose on page refresh(f5). Everything is working fine except when refresh the web page it is not possible to get the latest data from the api (because the data is taken from session storage).
Question:
- if it is correct way to use session storage for caching data?
- if true so what should i do so that when i refresh the web page, the data will come from api instead of session storage.
- if wrong so what is the correct way to caching data?
Target:
- [x] on first access, data comes from api (data write to cache after).
- [x] next time you visit. data coming from cache if have.
- [ ] on refresh, data comes from api regardless of cache presence or not (data override to cache after).
Screen code
...
const getter = {
get offset(): number {
return parseInt(searchParams.get("offset") ?? "0");
},
get limit(): number {
return parseInt(searchParams.get("limit") ?? "20");
},
};
const sessionCache = useSessionCache();
const [state, setState] = useState<PokesPageState>(initState);
const setStateOnly = (w: PokesPageState) => setState({ ...state, ...w });
useEffect(() => {
// -> get data promise
const getPokes = async (): Promise<PagingGeneric<Poke>> => {
const path = location.pathname + location.search;
return sessionCache.axiosPromise(path, () =>
axios_apis.poke.getPokes(getter.offset, getter.limit)
);
};
// -> set data to component state
getPokes()
.then((response) => setStateOnly({ pokes: response }))
.catch((e) => console.log(e));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [getter.limit, getter.offset]);
...
Hook:
export function useSessionCache() {
const sessionCache = {
get<T = any>(key: string): T | null {
const value = sessionStorage.getItem(key);
if (!value || value === "undefined") return null;
return JSON.parse(value);
},
set<T = any>(key: string, value: T): T {
sessionStorage.setItem(key, JSON.stringify(value));
return value;
},
async axiosPromise<T>(
key: string,
promise: () => Promise<AxiosResponse<T>>
): Promise<T> {
const value = sessionCache.get<T>(key);
if (value !== null) return value;
return await promise()
.then((response) => response.data)
.then((value) => sessionCache.set(key, value));
},
};
return sessionCache;
}
Api:
const poke_api = {
getPokes(offset: number, limit: number) {
const url = `/pokemon?offset=${offset}&limit=${limit}`;
return axios_request.get<PagingGeneric<Poke>>(url);
},
getPoke(noi: number | string) {
const url = `/pokemon/${noi}`;
return axios_request.get<PokeDetails>(url);
},
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|

