Storage Custom Hooks

Create reusable storage hooks

JavaScriptAdvanced
JavaScript
// Method 1: useLocalStorage hook (React-like)
function useLocalStorage(key, initialValue) {
    const [storedValue, setStoredValue] = (function() {
        try {
            const item = window.localStorage.getItem(key);
            return item ? JSON.parse(item) : initialValue;
        } catch (error) {
            return initialValue;
        }
    })();
    
    const setValue = function(value) {
        try {
            setStoredValue(value);
            window.localStorage.setItem(key, JSON.stringify(value));
        } catch (error) {
            console.error('Error setting localStorage:', error);
        }
    };
    
    return [storedValue, setValue];
}

// Usage
const [name, setName] = useLocalStorage('name', '');
setName('John');
console.log('Name:', name);

// Method 2: useSessionStorage hook
function useSessionStorage(key, initialValue) {
    const [storedValue, setStoredValue] = (function() {
        try {
            const item = window.sessionStorage.getItem(key);
            return item ? JSON.parse(item) : initialValue;
        } catch (error) {
            return initialValue;
        }
    })();
    
    const setValue = function(value) {
        try {
            setStoredValue(value);
            window.sessionStorage.setItem(key, JSON.stringify(value));
        } catch (error) {
            console.error('Error setting sessionStorage:', error);
        }
    };
    
    return [storedValue, setValue];
}

// Method 3: useStorage with options
function useStorage(key, initialValue, options = {}) {
    const storage = options.storage || localStorage;
    const serializer = options.serializer || JSON;
    
    const [storedValue, setStoredValue] = (function() {
        try {
            const item = storage.getItem(key);
            return item ? serializer.parse(item) : initialValue;
        } catch (error) {
            return initialValue;
        }
    })();
    
    const setValue = function(value) {
        try {
            setStoredValue(value);
            storage.setItem(key, serializer.stringify(value));
        } catch (error) {
            console.error('Storage error:', error);
        }
    };
    
    const removeValue = function() {
        try {
            storage.removeItem(key);
            setStoredValue(initialValue);
        } catch (error) {
            console.error('Remove error:', error);
        }
    };
    
    return [storedValue, setValue, removeValue];
}

// Method 4: Storage hook with expiration
function useStorageWithExpiry(key, initialValue, ttl) {
    const [storedValue, setStoredValue] = (function() {
        try {
            const item = localStorage.getItem(key);
            if (!item) return initialValue;
            
            const parsed = JSON.parse(item);
            if (Date.now() > parsed.expiry) {
                localStorage.removeItem(key);
                return initialValue;
            }
            
            return parsed.value;
        } catch (error) {
            return initialValue;
        }
    })();
    
    const setValue = function(value) {
        try {
            const item = {
                value: value,
                expiry: Date.now() + ttl
            };
            setStoredValue(value);
            localStorage.setItem(key, JSON.stringify(item));
        } catch (error) {
            console.error('Storage error:', error);
        }
    };
    
    return [storedValue, setValue];
}

// Method 5: Storage hook with sync
function useSyncedStorage(key, initialValue) {
    const [storedValue, setStoredValue] = (function() {
        try {
            const item = localStorage.getItem(key);
            return item ? JSON.parse(item) : initialValue;
        } catch (error) {
            return initialValue;
        }
    })();
    
    // Listen for changes from other tabs
    window.addEventListener('storage', function(e) {
        if (e.key === key) {
            setStoredValue(JSON.parse(e.newValue));
        }
    });
    
    const setValue = function(value) {
        try {
            setStoredValue(value);
            localStorage.setItem(key, JSON.stringify(value));
        } catch (error) {
            console.error('Storage error:', error);
        }
    };
    
    return [storedValue, setValue];
}

Output

Name: John

Custom hooks simplify storage usage.

Hook Pattern

  • Encapsulate logic
  • Provide simple API
  • Handle errors
  • Return values and setters

Hook Types

  • useLocalStorage
  • useSessionStorage
  • useStorage (generic)
  • useStorageWithExpiry
  • useSyncedStorage

Benefits

  • Reusable
  • Consistent API
  • Error handling
  • Type safety

Use Cases

  • React components
  • State management
  • User preferences
  • Form data

Best Practices

  • Handle errors
  • Provide defaults
  • Support options
  • Document usage