useSessionStorageState
State Management
A React hook that persists state in sessionStorage, maintaining data for the duration of a page session.
Demo
This counter persists across page refreshes but is cleared when closing the browser tab:
0
Installation
npm install @thibault.sh/hooks
Usage
import { useSessionStorageState } from '@thibault.sh/hooks/useSessionStorageState';
function FormWithAutosave() {
const [formData, setFormData] = useSessionStorageState('form-draft', {
title: '',
content: ''
});
return (
<form>
<input
value={formData.title}
onChange={(e) => setFormData(prev => ({
...prev,
title: e.target.value
}))}
placeholder="Title"
/>
<textarea
value={formData.content}
onChange={(e) => setFormData(prev => ({
...prev,
content: e.target.value
}))}
placeholder="Content"
/>
</form>
);
}
API
Parameters
key
stringThe sessionStorage key
initialValue
TThe initial value to use if no value exists in storage
Returns
A tuple containing the current value and a setter function
Features
- ✓Session Persistence
Data persists until the browser tab is closed
- ✓Page Refresh Safe
State survives page refreshes
- ✓Type Safety
Full TypeScript support with generics
- ✓Automatic Serialization
JSON serialization handled automatically
Form Draft Example
import { useSessionStorageState } from '@thibault.sh/hooks';
interface FormDraft {
title: string;
content: string;
lastSaved: string;
}
function BlogPostEditor() {
const [draft, setDraft] = useSessionStorageState<FormDraft>(
'blog-post-draft',
{
title: '',
content: '',
lastSaved: new Date().toISOString()
}
);
const updateDraft = (updates: Partial<FormDraft>) => {
setDraft(prev => ({
...prev,
...updates,
lastSaved: new Date().toISOString()
}));
};
return (
<div>
<h2>Draft Post</h2>
<p>Last saved: {new Date(draft.lastSaved).toLocaleString()}</p>
<input
value={draft.title}
onChange={(e) => updateDraft({ title: e.target.value })}
placeholder="Post title"
/>
<textarea
value={draft.content}
onChange={(e) => updateDraft({ content: e.target.value })}
placeholder="Write your post..."
/>
</div>
);
}
Wizard Form Example
import { useSessionStorageState } from '@thibault.sh/hooks';
interface WizardState {
currentStep: number;
steps: {
personalInfo: {
name: string;
email: string;
};
preferences: {
newsletter: boolean;
theme: string;
};
};
}
function FormWizard() {
const [wizardState, setWizardState] = useSessionStorageState<WizardState>(
'wizard-state',
{
currentStep: 1,
steps: {
personalInfo: { name: '', email: '' },
preferences: { newsletter: false, theme: 'light' }
}
}
);
const nextStep = () => {
setWizardState(prev => ({
...prev,
currentStep: prev.currentStep + 1
}));
};
return (
<div>
<h2>Step {wizardState.currentStep} of 2</h2>
{wizardState.currentStep === 1 ? (
<div>
<input
value={wizardState.steps.personalInfo.name}
onChange={(e) =>
setWizardState(prev => ({
...prev,
steps: {
...prev.steps,
personalInfo: {
...prev.steps.personalInfo,
name: e.target.value
}
}
}))
}
placeholder="Name"
/>
<button onClick={nextStep}>Next</button>
</div>
) : (
<div>
<select
value={wizardState.steps.preferences.theme}
onChange={(e) =>
setWizardState(prev => ({
...prev,
steps: {
...prev.steps,
preferences: {
...prev.steps.preferences,
theme: e.target.value
}
}
}))
}
>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
)}
</div>
);
}