Skip to content

Instantly share code, notes, and snippets.

@linus-jansson
Created April 18, 2024 07:46
Show Gist options
  • Save linus-jansson/34d24d759a75d6f9f714199271cdb37b to your computer and use it in GitHub Desktop.
Save linus-jansson/34d24d759a75d6f9f714199271cdb37b to your computer and use it in GitHub Desktop.
"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