Skip to content

Commit

Permalink
Merge pull request #144 from prgrms-fe-devcourse/143-feature/usefetch…
Browse files Browse the repository at this point in the history
…-caching

Feat: useFetch 캐싱 기능 추가
  • Loading branch information
shlee9999 authored Oct 4, 2024
2 parents c4deac9 + 08b86f8 commit 6fd15e3
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
Empty file.
13 changes: 11 additions & 2 deletions src/hooks/useFetch.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCacheStore } from '@/store/useCacheStore';
import replaceTextProperties from '@/utils/extractInnermostValues';
import { useEffect, useState } from 'react';
import { xml2json } from 'xml-js';
Expand All @@ -11,14 +12,22 @@ import { xml2json } from 'xml-js';
export default function useFetch<T>(url: string) {
const [data, setData] = useState<T>();
const [isLoading, setIsLoading] = useState(false);
const { caches, registerCache } = useCacheStore(state => state);

useEffect(() => {
if (caches[url]) {
setData(caches[url].data as T);
return;
}
const fetchData = async () => {
setIsLoading(true);
try {
const response = await fetch(url);
const xmlText = await response.text();
const jsonData = JSON.parse(xml2json(xmlText, { compact: true, spaces: 2 }));
setData(replaceTextProperties<T>(jsonData));
const parsedData = replaceTextProperties<T>(jsonData);
setData(parsedData);
registerCache(url, parsedData);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
Expand All @@ -27,7 +36,7 @@ export default function useFetch<T>(url: string) {
};

fetchData();
}, [url]);
}, [url, caches, registerCache]);

return { data, isLoading };
}
42 changes: 42 additions & 0 deletions src/store/useCacheStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { create } from 'zustand';

interface Cache {
data: unknown;
timestamp: number;
}

export const useCacheStore = create<{
caches: { [url: string]: Cache };
hasCache: (url: string) => boolean;
registerCache: (url: string, data: unknown) => void;
clear: (url: string) => void;
}>((set, get) => ({
caches: {},
hasCache: (url: string) => {
const cache = get().caches[url];
if (!cache) return false;
const currentTime = Date.now();
const expirationTime = 5 * 60 * 1000; // 5분 (밀리초 단위)
return currentTime - cache.timestamp < expirationTime;
},
registerCache: (url: string, data: unknown) => {
if (!get().hasCache(url)) {
set(state => ({
...state,
caches: {
...state.caches,
[url]: {
data,
timestamp: Date.now(),
},
},
}));
}
},
clear: (url: string) =>
set(state => {
const restCaches = { ...state.caches };
delete restCaches[url];
return { ...state, caches: restCaches };
}),
}));

0 comments on commit 6fd15e3

Please sign in to comment.