Created
April 18, 2024 07:46
-
-
Save linus-jansson/34d24d759a75d6f9f714199271cdb37b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use client"; | |
import { useState, useEffect } from 'react'; | |
const setQueryParams = <T>(key: string, value: T) => { | |
if (typeof window === 'undefined') | |
return undefined; | |
const url = new URL(window.location.href); | |
url.searchParams.set(key, JSON.stringify(value)); | |
window.history.pushState({}, '', url.toString()); | |
} | |
const getQueryParams = <T>(key: string, defaultValue: T): T | null => { | |
if (typeof window === 'undefined') | |
return null; | |
const url = new URL(window.location.href); | |
const data = url.searchParams.get(key); | |
if (data) { | |
return JSON.parse(data); | |
} | |
return defaultValue; | |
} | |
// Get item from localStorage safely | |
function getLocalStorage<T>(itemKey: string): T | undefined { | |
try { | |
if (typeof window !== 'undefined') { | |
const item = window.localStorage.getItem(itemKey); | |
return item ? JSON.parse(item) : undefined; | |
} | |
} catch (error) { | |
console.error("Error reading localStorage key", itemKey, ": ", error); | |
return undefined; // In case of error, return undefined to use default value | |
} | |
} | |
// Save item to localStorage safely | |
function saveLocalStorage<T>(itemKey: string, data: T) { | |
try { | |
if (typeof window !== 'undefined') { | |
const item = JSON.stringify(data); | |
window.localStorage.setItem(itemKey, item); | |
} | |
} catch (error) { | |
console.error("Error saving to localStorage:", error); | |
} | |
} | |
/* | |
Be careful with the data the is stored here. | |
All data will be stored in plaintext in the clients browser | |
This hook will store the state in the localstorage | |
to keep data between page reloads, | |
hook is wrapped around a regular useState hook | |
If for some reason the localstorage is not abailable | |
the hook will function as a regular useState | |
*/ | |
export const usePersistantState = <T>( | |
key: string, | |
defaultValue: T | |
): [T, React.Dispatch<React.SetStateAction<T>>] => { | |
const [state, setState] = useState<T>(defaultValue); | |
const [isFirstLoad, setIsFirstLoad] = useState(true); | |
const STATIC_PREFIX = "PERSISTANT_STATE_" | |
// Effect for getting state from localStorage | |
useEffect(() => { | |
const storedValue = getLocalStorage<T>(STATIC_PREFIX + key); | |
if (storedValue) { | |
setState(storedValue); | |
} | |
}, [key]); | |
// Effect for saving state to localStorage | |
useEffect(() => { | |
if (isFirstLoad) { | |
setIsFirstLoad(false); | |
return; | |
}; | |
saveLocalStorage(STATIC_PREFIX + key, state); | |
}, [state, key]); | |
return [state, setState]; | |
} | |
export const useQueryParams = <T>(key: string, defaultValue: T): [T, React.Dispatch<React.SetStateAction<T>>] => { | |
const [state, setState] = useState<T>(defaultValue); | |
// When state changes update the urls query params | |
useEffect(() => { | |
setQueryParams<T>(key, state); | |
}, [state, key]); | |
useEffect(() => { | |
const data = getQueryParams<T>(key, defaultValue); | |
if (data) { | |
setState(data); | |
} | |
}, [key]); | |
return [state, setState]; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment