diff --git a/package-lock.json b/package-lock.json index 5fe0210..191142c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "next": "15.4.5", "react": "19.1.0", "react-dom": "19.1.0", - "react-icons": "^5.5.0" + "react-icons": "^5.5.0", + "swr": "^2.3.6" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -2181,6 +2182,15 @@ } } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -3184,6 +3194,19 @@ } } }, + "node_modules/swr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.6.tgz", + "integrity": "sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/tailwindcss": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", @@ -3265,6 +3288,15 @@ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", diff --git a/package.json b/package.json index d7dbaa1..fc7685e 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "next": "15.4.5", "react": "19.1.0", "react-dom": "19.1.0", - "react-icons": "^5.5.0" + "react-icons": "^5.5.0", + "swr": "^2.3.6" }, "devDependencies": { "@tailwindcss/postcss": "^4", diff --git a/src/hooks/useSWRStorage/index.ts b/src/hooks/useSWRStorage/index.ts new file mode 100644 index 0000000..51422bd --- /dev/null +++ b/src/hooks/useSWRStorage/index.ts @@ -0,0 +1,30 @@ +import { useEffect } from "react"; +import useSWR, { SWRConfiguration } from "swr"; + +export const useSWRStorage = ( + key: string, + fetcher: (key: string) => Promise, + options: SWRConfiguration = {} +) => { + let fallbackData = + typeof window !== "undefined" && + JSON.parse(localStorage.getItem(key) || "null"); + + if (!fallbackData) { + fallbackData = options.fallbackData; + } + + const res = useSWR(key, fetcher, { + revalidateOnFocus: false, + ...options, + fallbackData, + }); + + useEffect(() => { + if (res.data) { + localStorage.setItem(key, JSON.stringify(res.data)); + } + }, [res.data]); + + return res; +};