Implementation:TobikoData Sqlmesh UseLocalStorage
| Knowledge Sources | |
|---|---|
| Domains | Web_UI, Browser_Storage |
| Last Updated | 2026-02-07 20:00 GMT |
Overview
React hook providing type-safe localStorage access with automatic JSON serialization and error handling.
Description
The useLocalStorage hook provides a simple, type-safe interface for persisting data to browser localStorage. It handles JSON serialization/deserialization, error handling, value merging on updates, and optional initial value setting. The hook returns a tuple of three functions for getting, setting, and removing stored values.
Usage
Use this hook when you need to persist user preferences, UI state, or application data across browser sessions. It simplifies localStorage operations by handling serialization and providing TypeScript type safety.
Code Reference
Source Location
- Repository: TobikoData_Sqlmesh
- File: web/client/src/hooks/useLocalStorage.ts
Signature
export default function useLocalStorage<T extends Record<string, any>>(
key: string,
initialValue?: T,
): [
() => Optional<T>, // getValue
(value: Partial<T>) => void, // setValue
() => void // removeKey
]
Import
import useLocalStorage from '~/hooks/useLocalStorage'
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| key | string | Yes | localStorage key for storing the value |
| initialValue | T | No | Optional initial value to set if key doesn't exist |
Outputs
| Name | Type | Description |
|---|---|---|
| getValue | () => Optional<T> | Function to retrieve the stored value |
| setValue | (value: Partial<T>) => void | Function to update the stored value (merges with existing) |
| removeKey | () => void | Function to delete the stored value |
Implementation Details
Automatic Initialization
If initialValue is provided, it's automatically stored to localStorage on hook creation. This ensures the key exists with a default value.
Value Merging
The setValue function merges partial updates with existing values:
const newValue = Object.assign({}, getValue(), value)
This allows incremental updates without overwriting the entire stored object.
Error Handling
All operations are wrapped in try/catch blocks:
- Read errors: Return undefined and log error
- Write errors: Silently fail and log error
- Parse errors: Handled by parseJSON utility
Type Safety
The generic type parameter T extends Record<string, any> ensures:
- Type-safe access to stored values
- Compile-time checking of property names
- IntelliSense support in editors
JSON Serialization
- Uses JSON.stringify for storage
- Uses custom parseJSON utility for retrieval
- Handles undefined values gracefully
Usage Examples
import useLocalStorage from '~/hooks/useLocalStorage'
// Simple preference storage
function UserPreferences() {
const [getPrefs, setPrefs, clearPrefs] = useLocalStorage<{
theme: string
fontSize: number
}>('user-prefs', { theme: 'light', fontSize: 14 })
const prefs = getPrefs()
// Update single property (merges with existing)
const changeTheme = () => {
setPrefs({ theme: 'dark' })
// fontSize remains unchanged
}
// Clear all preferences
const reset = () => {
clearPrefs()
}
return <div>Theme: {prefs?.theme}</div>
}
// Editor state persistence
function EditorState() {
const [getState, setState] = useLocalStorage<{
tabs: string[]
activeTab: string
}>('editor-state')
const state = getState()
// Add tab
const addTab = (tabId: string) => {
setState({
tabs: [...(state?.tabs ?? []), tabId],
activeTab: tabId
})
}
return <div>Active: {state?.activeTab}</div>
}
// Window layout persistence
const [getLayout, setLayout] = useLocalStorage<{
sidebar: number
editor: number
}>('layout', { sidebar: 20, editor: 80 })