1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-07-03 17:06:37 -04:00
This commit is contained in:
2025-03-20 08:30:28 -04:00
parent 5814576b0b
commit 3388da2d50
11 changed files with 555 additions and 183 deletions

View File

@ -3,23 +3,14 @@
import { useCallback, useState, useRef } from "react";
import type { Dispatch, SetStateAction } from "react";
const noop = () => {};
const useLocalStorage = <T = string>(
key: string,
initialValue?: T
): [T | undefined, Dispatch<SetStateAction<T | undefined>>, () => void] => {
if (typeof window === "undefined" || typeof window.Storage === "undefined") {
// immediately return a "dummy" hook instead of throwing an error if localStorage isn't available, either in the
// browser or because this hook is being called server-side.
return [initialValue as T, noop, noop];
}
// TODO: make these customizable (e.g. `JSON.stringify()` and `JSON.parse()`)
const serializer = (value: T | undefined) => String(value);
const deserializer = (value: string) => value as unknown as T;
// eslint-disable-next-line react-hooks/rules-of-hooks
const initializer = useRef((key: string) => {
try {
// deserialize and return existing value if it's already been set
@ -40,10 +31,8 @@ const useLocalStorage = <T = string>(
}
});
// eslint-disable-next-line react-hooks/rules-of-hooks
const [state, setState] = useState<T | undefined>(() => initializer.current(key));
// eslint-disable-next-line react-hooks/rules-of-hooks
const set: Dispatch<SetStateAction<T | undefined>> = useCallback(
(valOrFunc) => {
try {
@ -59,7 +48,6 @@ const useLocalStorage = <T = string>(
[key, state] // eslint-disable-line react-hooks/exhaustive-deps
);
// eslint-disable-next-line react-hooks/rules-of-hooks
const remove = useCallback(() => {
try {
window.localStorage.removeItem(key);