Skip to content

Instantly share code, notes, and snippets.

@SanariSan
Created December 24, 2023 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SanariSan/f174483c84862d9be80d826cf430e665 to your computer and use it in GitHub Desktop.
Save SanariSan/f174483c84862d9be80d826cf430e665 to your computer and use it in GitHub Desktop.
React persist state
import React from 'react';

/**
 * @param {string} storageKey
 * @param {*} initialState
 * @param {number} expiration
 */
export const useStateWithLocalStorage = (storageKey, initialState, expiration) => {
  const [value, setValue] = React.useState(() => {
    const value = localStorage.getItem(storageKey);
    if (null === value || 'undefined' === typeof value) {
      return initialState;
    }

    const expiration = parseInt(localStorage.getItem(`${storageKey}_expire`));
    if (!isNaN(expiration) && Math.floor(Date.now() / 1000) > expiration) {
      localStorage.removeItem(`${storageKey}_expire`);

      return initialState;
    }

    if ('{' === value[0] || '[' === value[0]) {
      return JSON.parse(value);
    }

    return value;
  });

  React.useEffect(() => {
    localStorage.setItem(storageKey, null !== value && 'object' === typeof value ? JSON.stringify(value) : value);

    if (expiration > 0) {
      const existingExpiration = localStorage.getItem(`${storageKey}_expire`);
      if (null === existingExpiration || 'undefined' === typeof existingExpiration) {
        localStorage.setItem(`${storageKey}_expire`, Math.floor(Date.now() / 1000) + expiration);
      }
    }
  }, [storageKey, value, expiration]);

  return [value, setValue];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment