aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/hooks/use-local-storage/use-local-storage.ts
blob: 47b98ff44fd0885cc8d6cf88394eea3ba21cf940 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { useEffect, useState } from 'react';
import { LocalStorage } from '../../../services/local-storage';
import type { Validator } from '../../../types';

const getInitialValueOrFallback = <T>(
  key: string,
  fallbackValue: T,
  validator: Validator<T>
) => {
  if (typeof window === 'undefined') return fallbackValue;
  const storedValue = LocalStorage.get(key);

  return validator(storedValue) ? storedValue : fallbackValue;
};

/**
 * Use the local storage.
 *
 * @param {string} key - The storage local key.
 * @param {T} fallbackValue - A fallback value if local storage is empty.
 * @param {Validator<T>} validator - A function to validate the stored value.
 * @returns A tuple with the value and a setter.
 */
export const useLocalStorage = <T>(
  key: string,
  fallbackValue: T,
  validator: Validator<T>
) => {
  const [value, setValue] = useState(
    getInitialValueOrFallback(key, fallbackValue, validator)
  );

  useEffect(() => {
    LocalStorage.set(key, value);
  }, [key, value]);

  return [value, setValue] as const;
};