MCPcopy Create free account
hub / github.com/bvaughn/react-window / useLocalStorage

Function useLocalStorage

src/hooks/useLocalStorage.ts:3–61  ·  view source on GitHub ↗
(
  key: string,
  defaultValue: Type
)

Source from the content-addressed store, hash-verified

1import { useLayoutEffect, useRef, useState } from "react";
2
3export default function useLocalStorage<Type>(
4 key: string,
5 defaultValue: Type
6): [value: Type, setValue: (newValue: Type) => void] {
7 const [value, setValue] = useState<Type>(() => {
8 const storedValue = localStorage.getItem(key);
9 if (storedValue != null) {
10 return JSON.parse(storedValue) as Type;
11 } else {
12 return defaultValue;
13 }
14 });
15
16 const committedValuesRef = useRef<{
17 prevValue: string | null;
18 value: string;
19 }>({
20 prevValue: null,
21 value: JSON.stringify(value)
22 });
23 useLayoutEffect(() => {
24 committedValuesRef.current.prevValue = committedValuesRef.current.value;
25 committedValuesRef.current.value = JSON.stringify(value);
26 });
27
28 // Sync changes from local storage
29 useLayoutEffect(() => {
30 const onStorage = (event: StorageEvent) => {
31 if (
32 key === event.key &&
33 event.newValue &&
34 event.newValue !== JSON.stringify(value)
35 ) {
36 setValue(JSON.parse(event.newValue));
37 }
38 };
39
40 window.addEventListener("storage", onStorage);
41
42 return () => {
43 window.removeEventListener("storage", onStorage);
44 };
45 }, [key, value]);
46
47 // Sync changes to local storage
48 useLayoutEffect(() => {
49 window.dispatchEvent(
50 new StorageEvent("storage", {
51 key,
52 newValue: committedValuesRef.current.value || "",
53 oldValue: committedValuesRef.current.prevValue || ""
54 })
55 );
56
57 localStorage.setItem(key, committedValuesRef.current.value);
58 }, [key, value]);
59
60 return [value, setValue];

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected