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