@kadconsulting/dry
Version:
KAD Reusable Component Library
63 lines (62 loc) • 2.95 kB
TypeScript
import { type LocalStorageValueType, type UseLocalStorageOptions, type StorageWriteOperationOptions } from './types';
/** Expose these values in the module so that tests can mock localStorage implementation */
export declare const FEATURE_DETECTION_TEST_KEY = "test-key";
export declare const FEATURE_DETECTION_TEST_VALUE = "test-value";
/**
* @name useLocalStorageForKey
* @description
* Abstracts away cumbersome serialization/deserialization, error handling,
* feature detection, SSR and type casting when using localStorage. Can also
* condense call signatures slightly by constraining usage to one key at a time.
*
* @example
* Here, we're letting the hook know that it's parsing an object type. We use
* the shouldThrow option when calling set in order to log some hypothetical
* warning about a user's degraded experience for analytics purposes if the set
* operation fails.
* ```
* // Consume the hook
* const currentUser = useLocalStorageForKey(
* LocalStorageKeys.CURRENT_USER,
* { valueType: LocalStorageValueTypes.OBJECT }
* );
*
* // ...later, in some callback
*
* try {
* if (currentUser.get()) return; // User already cached, no need to fetch
* // Use HTTP-only cookie to fetch current user
* const response = await fetch('/api/current-user');
* const currentUser = await response.json();
* // Cache the current user so that subsequent visits don't require a round-trip to the server
* const storageCurrentUser.set(currentUser, { shouldThrow: true });
* } catch (error) {
* await logger.warn(`Unable to set currentUser in localStorage: ${error.message}. User ${currentUser.id} will face increased round-trip latency on subsequent visits due to lack of cache.`)
* }}
* ```
* @example
* Here, we've used localStorage to cache whether the user responded to a
* legal drinking age prompt. We use the debug option to log errors to the console.
* We use the value returned to prevent the modal from showing on subsequent visits.
* We swallow any errors by not opting into error handling via the `shouldThrow`
* option, because it's not the end of the world if the user has to see the modal
* again on subsequent visits.
* ```
* // Consume the hook, use the result to set initial state
* const didAcknowlegeAgeRestriction = useLocalStorageForKey(
* LocalStorageKeys.DID_ACKNOWLEDGE_AGE_RESTRICTION,
* { debug: true, valueType: LocalStorageValueTypes.BOOLEAN }
* )
*
* const [
* shouldShowLegalDrinkingAgeModal,
* setShouldShowLegalDrinkingAgeModal
* ] = useState(didAcknowlegeAgeRestrictionStorage.get() || false)
* ```
*/
export declare const useLocalStorageForKey: <Value extends LocalStorageValueType>(key: string, { debug, valueType, }: UseLocalStorageOptions) => {
get: () => Value | null;
set: (value: Value, options?: StorageWriteOperationOptions) => void;
remove: (options?: StorageWriteOperationOptions) => void | Error;
isSupported: boolean;
};