diff options
Diffstat (limited to 'node_modules/@phntms/use-local-state/src/index.ts')
-rwxr-xr-x | node_modules/@phntms/use-local-state/src/index.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/node_modules/@phntms/use-local-state/src/index.ts b/node_modules/@phntms/use-local-state/src/index.ts new file mode 100755 index 0000000..face65b --- /dev/null +++ b/node_modules/@phntms/use-local-state/src/index.ts @@ -0,0 +1,52 @@ +import { useState, useCallback, useRef } from "react"; + +import { SUPPORTED } from "./utils"; + +type Dispatch<A> = (value: A) => void; +type SetStateAction<S> = S | ((prevState: S) => S); + +const useLocalState = <S>( + key: string, + defaultValue: S | (() => S) +): [S, Dispatch<SetStateAction<S>>, () => void] => { + const [value, setValue] = useState<S>(() => { + const isCallable = (value: unknown): value is () => S => + typeof value === "function"; + const toStore = isCallable(defaultValue) ? defaultValue() : defaultValue; + if (!SUPPORTED) return toStore; + const item = window.localStorage.getItem(key); + try { + return item ? JSON.parse(item) : toStore; + } catch (error) { + return toStore; + } + }); + + const lastValue = useRef(value); + lastValue.current = value; + + const setLocalStateValue = useCallback( + (newValue: SetStateAction<S>) => { + const isCallable = (value: unknown): value is (prevState: S) => S => + typeof value === "function"; + const toStore = isCallable(newValue) + ? newValue(lastValue.current) + : newValue; + if (SUPPORTED) window.localStorage.setItem(key, JSON.stringify(toStore)); + setValue(toStore); + }, + [key] + ); + + const reset = useCallback(() => { + const isCallable = (value: unknown): value is (prevState: S) => S => + typeof value === "function"; + const toStore = isCallable(defaultValue) ? defaultValue() : defaultValue; + setValue(toStore); + if (SUPPORTED) window.localStorage.removeItem(key); + }, [defaultValue, key]); + + return [value, setLocalStateValue, reset]; +}; + +export default useLocalState; |