1 | import { useCallback, useState, useRef, useLayoutEffect } from 'react';
|
---|
2 | import { isBrowser, noop } from './misc/util';
|
---|
3 | var useLocalStorage = function (key, initialValue, options) {
|
---|
4 | if (!isBrowser) {
|
---|
5 | return [initialValue, noop, noop];
|
---|
6 | }
|
---|
7 | if (!key) {
|
---|
8 | throw new Error('useLocalStorage key may not be falsy');
|
---|
9 | }
|
---|
10 | var deserializer = options
|
---|
11 | ? options.raw
|
---|
12 | ? function (value) { return value; }
|
---|
13 | : options.deserializer
|
---|
14 | : JSON.parse;
|
---|
15 | // eslint-disable-next-line react-hooks/rules-of-hooks
|
---|
16 | var initializer = useRef(function (key) {
|
---|
17 | try {
|
---|
18 | var serializer = options ? (options.raw ? String : options.serializer) : JSON.stringify;
|
---|
19 | var localStorageValue = localStorage.getItem(key);
|
---|
20 | if (localStorageValue !== null) {
|
---|
21 | return deserializer(localStorageValue);
|
---|
22 | }
|
---|
23 | else {
|
---|
24 | initialValue && localStorage.setItem(key, serializer(initialValue));
|
---|
25 | return initialValue;
|
---|
26 | }
|
---|
27 | }
|
---|
28 | catch (_a) {
|
---|
29 | // If user is in private mode or has storage restriction
|
---|
30 | // localStorage can throw. JSON.parse and JSON.stringify
|
---|
31 | // can throw, too.
|
---|
32 | return initialValue;
|
---|
33 | }
|
---|
34 | });
|
---|
35 | // eslint-disable-next-line react-hooks/rules-of-hooks
|
---|
36 | var _a = useState(function () { return initializer.current(key); }), state = _a[0], setState = _a[1];
|
---|
37 | // eslint-disable-next-line react-hooks/rules-of-hooks
|
---|
38 | useLayoutEffect(function () { return setState(initializer.current(key)); }, [key]);
|
---|
39 | // eslint-disable-next-line react-hooks/rules-of-hooks
|
---|
40 | var set = useCallback(function (valOrFunc) {
|
---|
41 | try {
|
---|
42 | var newState = typeof valOrFunc === 'function' ? valOrFunc(state) : valOrFunc;
|
---|
43 | if (typeof newState === 'undefined')
|
---|
44 | return;
|
---|
45 | var value = void 0;
|
---|
46 | if (options)
|
---|
47 | if (options.raw)
|
---|
48 | if (typeof newState === 'string')
|
---|
49 | value = newState;
|
---|
50 | else
|
---|
51 | value = JSON.stringify(newState);
|
---|
52 | else if (options.serializer)
|
---|
53 | value = options.serializer(newState);
|
---|
54 | else
|
---|
55 | value = JSON.stringify(newState);
|
---|
56 | else
|
---|
57 | value = JSON.stringify(newState);
|
---|
58 | localStorage.setItem(key, value);
|
---|
59 | setState(deserializer(value));
|
---|
60 | }
|
---|
61 | catch (_a) {
|
---|
62 | // If user is in private mode or has storage restriction
|
---|
63 | // localStorage can throw. Also JSON.stringify can throw.
|
---|
64 | }
|
---|
65 | }, [key, setState]);
|
---|
66 | // eslint-disable-next-line react-hooks/rules-of-hooks
|
---|
67 | var remove = useCallback(function () {
|
---|
68 | try {
|
---|
69 | localStorage.removeItem(key);
|
---|
70 | setState(undefined);
|
---|
71 | }
|
---|
72 | catch (_a) {
|
---|
73 | // If user is in private mode or has storage restriction
|
---|
74 | // localStorage can throw.
|
---|
75 | }
|
---|
76 | }, [key, setState]);
|
---|
77 | return [state, set, remove];
|
---|
78 | };
|
---|
79 | export default useLocalStorage;
|
---|