https://github.com/umarsiddique010/use-localstorage-hook
https://github.com/umarsiddique010/use-localstorage-hook
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/umarsiddique010/use-localstorage-hook
- Owner: umarSiddique010
- Created: 2025-06-19T15:50:41.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-06-19T15:50:56.000Z (about 1 year ago)
- Last Synced: 2025-06-19T16:29:47.956Z (about 1 year ago)
- Language: JavaScript
- Size: 0 Bytes
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# useLocalstorage
A React hook for safe, reactive access to `localStorage`, with:
* Reactive state management with automatic re-renders
* Cross-tab synchronization via storage events
* Auto-initialization on mount with validation
* Built-in `set`, `get`, `remove`, `clearAll` helpers
* Support for any JSON-serializable data
* Error-resilient design with comprehensive error handling
* Zero dependencies — just native Web APIs + React
---
## Why Use This Hook?
> No more repeating `localStorage.setItem` logic in every component.
`useLocalstorage` is for React developers who want:
* Reactive localStorage state that updates your UI automatically
* Cross-tab synchronization - changes in one tab update others
* One-liner setup of persistent browser state
* Safety against stale keys or malformed data
* Clean `set/get/remove` operations without spaghetti
* Auto-persisted defaults on first load
* Reusability across apps, components, and projects
**Perfect for:**
* Auth tokens or user session keys
* UI preferences (dark mode, language)
* Cart data or product filters
* Any local-only persistence logic that needs cross-tab sync
---
## What Is This?
`useLocalstorage()` is a custom React hook that wraps the native `localStorage` API in a safe, reactive, composable way.
It handles:
* Reactive state management with `useState`
* Cross-tab synchronization with storage events
* When to write to localStorage (`useEffect`)
* How to write (with stringification and error handling)
* Reading, removing, and clearing browser keys
* Making it all memoized and safe for reuse
---
## Installation
```bash
npm install @mdus/use-localstorage-hook
# or
yarn add @mdus/use-localstorage-hook
```
---
## API Reference
### What It Expects
| Argument | Type | Required | Description |
| ------------- | -------- | -------- | ------------------------------------------------------- |
| `storeName` | `string` | Yes | The key to use inside localStorage |
| `initialData` | `any` | Yes | The default data to initialize if the key is empty/null |
### What It Returns
| Key | Type | Description |
| --------------- | ---------- | -------------------------------------------------------------- |
| `getStore` | `any` | The current value from localStorage (reactive state) |
| `setStore` | `function` | Sets a value into `localStorage` and updates the reactive state |
| `removeStore` | `function` | Removes the item with this key from localStorage |
| `clearAllStore` | `function` | Clears **all** localStorage entries |
---
## Usage
### 1. Basic Reactive State
```jsx
import useLocalstorage from "@mdus/use-localstorage-hook";
function ThemeToggle() {
const { getStore: theme, setStore: setTheme } = useLocalstorage("theme", "light");
const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light");
};
return (
Current theme: {theme}
Toggle Theme
);
}
```
### 2. Cross-Tab Synchronization
```jsx
function UserPreferences() {
const { getStore: prefs, setStore: setPrefs } = useLocalstorage("userPrefs", {
language: "en",
notifications: true
});
// This will automatically update across all open tabs
const updateLanguage = (lang) => {
setPrefs({ ...prefs, language: lang });
};
return (
Language: {prefs.language}
updateLanguage("es")}>Switch to Spanish
);
}
```
### 3. Managing Complex Data
```jsx
function ShoppingCart() {
const { getStore: cart, setStore: setCart, removeStore } = useLocalstorage("cart", []);
const addItem = (item) => {
setCart([...cart, item]);
};
const clearCart = () => {
removeStore();
};
return (
Items in cart: {cart.length}
addItem({ id: Date.now(), name: "Product" })}>
Add Item
Clear Cart
);
}
```
---
## Key Features
### 1. Reactive State Management
The hook uses `useState` to provide reactive state that automatically re-renders your components when localStorage changes:
```js
const [getStore, setGetStore] = useState(() => {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : initialData;
} catch (err) {
console.error(`Error reading localStorage key "${key}":`, err);
localStorage.removeItem(key);
return initialData;
}
});
```
### 2. Cross-Tab Synchronization
The hook listens for storage events to keep multiple tabs in sync:
```js
useEffect(() => {
const handleStoreChange = (e) => {
if (e.key === key) {
try {
if (e.newValue === null) {
setGetStore(null);
} else {
setGetStore(JSON.parse(e.newValue));
}
} catch (err) {
console.error(`Error parsing storage event for key "${key}":`, err);
setGetStore(null);
}
}
};
window.addEventListener('storage', handleStoreChange);
return () => window.removeEventListener('storage', handleStoreChange);
}, [key]);
```
### 3. Safe Initialization
The hook validates inputs and safely initializes localStorage:
```js
if (!storeName || initialData === undefined) {
throw new Error("useLocalstorage: storeName and initialData are required.");
}
```
### 4. Error Resilience
All operations are wrapped in try/catch blocks with meaningful error messages and fallback behavior.
---
## Internals
### Lifecycle-Safe Initialization
When the component mounts, the hook checks if localStorage already contains the key:
```js
useEffect(() => {
try {
const existing = localStorage.getItem(key);
if (existing === null) {
setStore(initialData);
}
} catch (err) {
console.error(`Error initializing localStorage key "${key}":`, err);
}
}, [key, initialData, setStore]);
```
This prevents overwriting existing values.
### Pure React API
* Uses `useState` for reactive state management
* Uses `useCallback` to memoize methods
* Uses `useEffect` for storage event listeners and initialization
* Safe to use inside other hooks and effects
* Designed for composability in any React component
---
## File Structure
```
use-localstorage-hook/
├── src/
│ └── useLocalstorage.js
├── dist/
│ └── index.js
├── package.json
└── README.md
```
---
## Author
**Md Umar Siddique**
* GitHub: [@umarSiddique010](https://github.com/umarSiddique010)
* LinkedIn: [md-umar-siddique](https://linkedin.com/in/md-umar-siddique)
* Dev.to: [@umarSiddique010](https://dev.to/umarsiddique010)
---
## License
MIT © 2025 Md Umar Siddique
---
## Final Note
This hook solves a **real problem**: managing persistent state in a clean, reactive, and React-friendly way with cross-tab synchronization. It reflects an engineering mindset focused on **clarity**, **reusability**, **reactivity**, and **edge case safety** — all in under 3KB of code.
If it saves you time, please consider starring and sharing.