diff --git a/src/index.ts b/src/index.ts index abc4e16..078de67 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import { useEffect, useMemo, useRef, useState } from "react"; type Serializer = (object: T | undefined) => string; type Parser = (val: string) => T | undefined; type Setter = React.Dispatch>; +type DefaultValue = T | (() => T) type Options = Partial<{ serializer: Serializer; @@ -13,12 +14,12 @@ type Options = Partial<{ function useLocalStorage( key: string, - defaultValue: T, + defaultValue: DefaultValue, options?: Options ): [T, Setter]; function useLocalStorage( key: string, - defaultValue?: T, + defaultValue?: DefaultValue, options?: Options ) { const opts = useMemo(() => { @@ -36,17 +37,18 @@ function useLocalStorage( const rawValueRef = useRef(null); const [value, setValue] = useState(() => { - if (typeof window === "undefined") return defaultValue; + const newValue = defaultValue instanceof Function ? defaultValue() : defaultValue + if (typeof window === "undefined") return newValue; try { rawValueRef.current = window.localStorage.getItem(key); const res: T = rawValueRef.current ? parser(rawValueRef.current) - : defaultValue; + : newValue; return res; } catch (e) { logger(e); - return defaultValue; + return newValue; } }); diff --git a/test/useLocalStorage.test.tsx b/test/useLocalStorage.test.tsx index 6d74889..d81b9b8 100644 --- a/test/useLocalStorage.test.tsx +++ b/test/useLocalStorage.test.tsx @@ -36,6 +36,11 @@ export function TestComponent() { ); } +function WithLazyInitialState({ text }: { text: string }) { + const [data] = useLocalStorage("username", () => text); + return

{data}

; +} + function WithCustomParser() { const [data] = useLocalStorage("username", "John Doe", { parser: (val) => JSON.parse(val) + "kraw", @@ -174,6 +179,10 @@ describe("useLocalStorage", () => { JSON.stringify("foobarbarbarbar") ); }); + it("uses a lazy initial state", () => { + const { container } = render(); + expect(container.querySelector("p")).toHaveTextContent("johndoe85kraw"); + }); it("uses a custom parser", () => { localStorage.setItem("username", JSON.stringify("johndoe85")); const { container } = render();