useReadLocalStorage
Custom hook that reads a value from localStorage, closely related to useLocalStorage().
Usage
import { useReadLocalStorage } from 'usehooks-ts' export default function Component() { // Assuming a value was set in localStorage with this key const darkMode = useReadLocalStorage('darkMode') return <p>DarkMode is {darkMode ? 'enabled' : 'disabled'}</p> } API
▸ useReadLocalStorage<T>(key, options): T | null | undefined
Custom hook that reads a value from localStorage, closely related to useLocalStorage().
Type parameters
| Name | Description |
|---|---|
T | The type of the stored value. |
Parameters
| Name | Type | Description |
|---|---|---|
key | string | The key associated with the value in local storage. |
options | Options<T, false> | Additional options for reading the value (optional). |
Returns
T | null | undefined
The stored value, or null if the key is not present or an error occurs.
▸ useReadLocalStorage<T>(key, options?): T | null
Custom hook that reads a value from localStorage, closely related to useLocalStorage().
Type parameters
| Name | Description |
|---|---|
T | The type of the stored value. |
Parameters
| Name | Type | Description |
|---|---|---|
key | string | The key associated with the value in local storage. |
options? | Partial<Options<T, true>> | Additional options for reading the value (optional). |
Returns
T | null
The stored value, or null if the key is not present or an error occurs.
Type aliases
Ƭ Options<T, InitializeWithValue>: Object
Represents the type for the options available when reading from local storage.
Type parameters
| Name | Type | Description |
|---|---|---|
T | T | The type of the stored value. |
InitializeWithValue | extends boolean | undefined | - |
Type declaration
| Name | Type | Description |
|---|---|---|
deserializer? | (value: string) => T | Custom deserializer function to convert the stored string value to the desired type (optional). |
initializeWithValue | InitializeWithValue | If true (default), the hook will initialize reading the local storage. In SSR, you should set it to false, returning undefined initially. |
Hook
import { useCallback, useEffect, useState } from 'react' import { useEventListener } from 'usehooks-ts' const IS_SERVER = typeof window === 'undefined' type Options<T, InitializeWithValue extends boolean | undefined> = { deserializer?: (value: string) => T initializeWithValue: InitializeWithValue } // SSR version export function useReadLocalStorage<T>( key: string, options: Options<T, false>, ): T | null | undefined // CSR version export function useReadLocalStorage<T>( key: string, options?: Partial<Options<T, true>>, ): T | null export function useReadLocalStorage<T>( key: string, options: Partial<Options<T, boolean>> = {}, ): T | null | undefined { let { initializeWithValue = true } = options if (IS_SERVER) { initializeWithValue = false } const deserializer = useCallback<(value: string) => T | null>( value => { if (options.deserializer) { return options.deserializer(value) } // Support 'undefined' as a value if (value === 'undefined') { return undefined as unknown as T } let parsed: unknown try { parsed = JSON.parse(value) } catch (error) { console.error('Error parsing JSON:', error) return null } return parsed as T }, [options], ) // Get from local storage then // parse stored json or return initialValue const readValue = useCallback((): T | null => { // Prevent build error "window is undefined" but keep keep working if (IS_SERVER) { return null } try { const raw = window.localStorage.getItem(key) return raw ? deserializer(raw) : null } catch (error) { console.warn(`Error reading localStorage key “${key}”:`, error) return null } }, [key, deserializer]) const [storedValue, setStoredValue] = useState(() => { if (initializeWithValue) { return readValue() } return undefined }) // Listen if localStorage changes useEffect(() => { setStoredValue(readValue()) // eslint-disable-next-line react-hooks/exhaustive-deps }, [key]) const handleStorageChange = useCallback( (event: StorageEvent | CustomEvent) => { if ((event as StorageEvent).key && (event as StorageEvent).key !== key) { return } setStoredValue(readValue()) }, [key, readValue], ) // this only works for other documents, not the current one useEventListener('storage', handleStorageChange) // this is a custom event, triggered in writeValueToLocalStorage // See: useLocalStorage() useEventListener('local-storage', handleStorageChange) return storedValue }