State Management
useSessionstorageState
About
A hook that provides state management synchronized with sessionStorage. It automatically persists state changes to sessionStorage and provides real-time synchronization across browser windows and tabs. The hook handles JSON serialization/deserialization automatically and provides a clean API similar to React's useState.
Examples
Basic example
import { useSessionstorageState } from "rooks";
export default function App() {
const [count, setCount] = useSessionstorageState("my-app:count", 0);
return (
<div className="App">
<h1>Session Storage Counter</h1>
<p>Count: {count}</p>
<p>Refresh the page to see the value persisted!</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}Complex object storage
import { useSessionstorageState } from "rooks";
export default function UserProfile() {
const [user, setUser] = useSessionstorageState("user-profile", {
name: "",
email: "",
preferences: {
theme: "light",
notifications: true
}
});
const updateUser = (field, value) => {
setUser(prev => ({
...prev,
[field]: value
}));
};
const updatePreferences = (pref, value) => {
setUser(prev => ({
...prev,
preferences: {
...prev.preferences,
[pref]: value
}
}));
};
return (
<div>
<h2>User Profile</h2>
<input
placeholder="Name"
value={user.name}
onChange={(e) => updateUser("name", e.target.value)}
/>
<input
placeholder="Email"
value={user.email}
onChange={(e) => updateUser("email", e.target.value)}
/>
<label>
<input
type="checkbox"
checked={user.preferences.notifications}
onChange={(e) => updatePreferences("notifications", e.target.checked)}
/>
Enable notifications
</label>
<select
value={user.preferences.theme}
onChange={(e) => updatePreferences("theme", e.target.value)}
>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
);
}Cross-window synchronization with remove functionality
import { useSessionstorageState } from "rooks";
export default function SyncDemo() {
const [message, setMessage, removeMessage] = useSessionstorageState(
"sync-message",
"Hello World"
);
const [lastUpdated, setLastUpdated] = useSessionstorageState(
"last-updated",
Date.now()
);
const updateMessage = (newMessage) => {
setMessage(newMessage);
setLastUpdated(Date.now());
};
const clearAll = () => {
removeMessage();
setLastUpdated(Date.now());
};
return (
<div>
<h2>Cross-Window Sync Demo</h2>
<p>Open this page in multiple tabs to see real-time synchronization!</p>
<div>
<strong>Current Message:</strong> {message || "No message"}
</div>
<div>
<strong>Last Updated:</strong> {new Date(lastUpdated).toLocaleTimeString()}
</div>
<input
value={message || ""}
onChange={(e) => updateMessage(e.target.value)}
placeholder="Type a message..."
/>
<button onClick={() => updateMessage("Updated from tab!")}>
Update Message
</button>
<button onClick={clearAll}>
Clear Message
</button>
<p>
<em>Try changing the message in one tab and watch it update in others!</em>
</p>
</div>
);
}Arguments
| Argument | Type | Description | Default |
|---|---|---|---|
| key | string | The sessionStorage key to use for persistence | - |
| initialState | S | (() => S) | Initial state value or function that returns initial state | - |
Returns
Returns an array with three elements:
| Return value | Type | Description |
|---|---|---|
| value | S | Current state value, synchronized with sessionStorage |
| setValue | Dispatch<SetStateAction<S>> | Function to update the state (similar to useState) |
| remove | () => void | Function to remove the item from sessionStorage |
Features
Automatic Persistence
- State changes are automatically saved to sessionStorage
- Values are JSON serialized/deserialized automatically
- Handles complex objects, arrays, and primitive values
Cross-Window Synchronization
- Changes in one browser tab/window automatically sync to other tabs/windows
- Uses native
storageevents for cross-document communication - Real-time updates without page refresh
Within-Document Synchronization
- Multiple instances of the same hook with the same key stay synchronized
- Uses custom events for efficient within-document communication
- Prevents infinite update loops
Error Handling
- Gracefully handles JSON parsing errors
- Safe fallback when sessionStorage is unavailable (SSR)
- Console warnings for debugging in non-browser environments
Memory Management
- Automatically cleans up event listeners on unmount
- Optimized re-renders using useCallback and useRef
- No memory leaks from event listeners
Notes
- The hook is SSR-safe and handles cases where
windoworsessionStorageare undefined - Values are stored as JSON strings, so only JSON-serializable values are supported
- sessionStorage data persists until the browser tab is closed (unlike localStorage which persists indefinitely)
- Cross-window synchronization only works within the same domain and browser session