Synchronize React component state with local storage
- Published on
- Published on
- /2 mins read/...
Simple custom hook to synchronize component state with local storage.
use-local-storage-state.ts
import { useState, useEffect } from 'react'
export function useLocalStorageState<T = { [key: string]: any }>(key: string, defaultValue?: T) {
let [state, setState] = useState<T>(() => {
let storage = localStorage.getItem(key)
if (storage) {
return JSON.parse(storage)
}
return defaultValue || {}
})
useEffect(() => {
localStorage.setItem(key, JSON.stringify(state))
}, [state])
// Using `as const` to ensure the type of the returned array is correct
return [state, setState] as const
}
In some cases, you might need to check for browser environment, cause local storage is available only in the client side.
use-local-storage-state.ts
import { useState, useEffect } from 'react'
let isBrowser = typeof window !== 'undefined' // Check for browser/client environment
export function useLocalStorageState<T = { [key: string]: any }>(key: string, defaultValue?: T) {
let [state, setState] = useState<T>(() => {
if (isBrowser) {
let storage = localStorage.getItem(key)
if (storage) {
return JSON.parse(storage)
}
}
return defaultValue || {}
})
useEffect(() => {
localStorage.setItem(key, JSON.stringify(state))
}, [state])
return [state, setState] as const
}
Usage
A simple example of using the hook to synchronize component state with local storage is shown below:
theme-switcher.tsx
function ThemeSwitcher() {
let [theme, setTheme] = useLocalStorageState<'dark' | 'light'>('theme', 'light')
return (
<select onChange={ev => setTheme(ev.target.value)}>
<option value="dark">Dark</option>
<option value="light">Light</option>
</select>
)
}