A comprehensive collection of 75+ React hooks for state and UI management including storage, events, browser APIs, and performance optimizations
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
localStorage and sessionStorage integration with serialization, synchronization across tabs, and SSR support for persistent application state.
localStorage integration with serialization, synchronization, and SSR support.
/**
* localStorage integration with type safety and serialization
* @param props - Configuration object
* @returns Tuple of current value, setter, and remover
*/
function useLocalStorage<T = string>(props: UseStorageOptions<T>): UseStorageReturnValue<T>;
/**
* Read localStorage value without creating a hook
* @param props - Configuration object
* @returns Current value from localStorage
*/
function readLocalStorageValue<T>(props: UseStorageOptions<T>): T;
interface UseStorageOptions<T> {
key: string;
defaultValue?: T;
getInitialValueInEffect?: boolean;
sync?: boolean;
serialize?: (value: T) => string;
deserialize?: (value: string | undefined) => T;
}
type UseStorageReturnValue<T> = [
T, // current value
(val: T | ((prevState: T) => T)) => void, // setter
() => void // remover
];Usage Examples:
import { useLocalStorage } from "@mantine/hooks";
// String storage
const [name, setName, removeName] = useLocalStorage({
key: 'user-name',
defaultValue: 'Anonymous'
});
// Object storage with custom serialization
const [settings, setSettings] = useLocalStorage({
key: 'app-settings',
defaultValue: { theme: 'light', lang: 'en' },
serialize: JSON.stringify,
deserialize: (str) => str ? JSON.parse(str) : { theme: 'light', lang: 'en' }
});
// Cross-tab synchronization
const [count, setCount] = useLocalStorage({
key: 'shared-count',
defaultValue: 0,
sync: true // Syncs across tabs
});
// SSR-safe initialization
const [token, setToken] = useLocalStorage({
key: 'auth-token',
defaultValue: '',
getInitialValueInEffect: true // Prevents hydration mismatch
});
// Usage
setName('John Doe');
setSettings(prev => ({ ...prev, theme: 'dark' }));
removeName(); // Removes from localStorage and resets to defaultsessionStorage integration with the same features as useLocalStorage but for session-only persistence.
/**
* sessionStorage integration with type safety and serialization
* @param props - Configuration object
* @returns Tuple of current value, setter, and remover
*/
function useSessionStorage<T = string>(props: UseStorageOptions<T>): UseStorageReturnValue<T>;
/**
* Read sessionStorage value without creating a hook
* @param props - Configuration object
* @returns Current value from sessionStorage
*/
function readSessionStorageValue<T>(props: UseStorageOptions<T>): T;Usage Examples:
import { useSessionStorage } from "@mantine/hooks";
// Form data that persists only during session
const [formData, setFormData, clearForm] = useSessionStorage({
key: 'form-draft',
defaultValue: {
title: '',
content: '',
tags: []
}
});
// Temporary UI state
const [sidebarCollapsed, setSidebarCollapsed] = useSessionStorage({
key: 'sidebar-state',
defaultValue: false
});
// Shopping cart for session
const [cart, setCart] = useSessionStorage({
key: 'session-cart',
defaultValue: [],
sync: true // Sync across tabs in same session
});
// Usage
setFormData(prev => ({ ...prev, title: 'New Article' }));
setSidebarCollapsed(true);
clearForm(); // Clears sessionStorage and resets to defaultimport { useLocalStorage, useSessionStorage } from "@mantine/hooks";
function ContactForm() {
// Persist draft across browser sessions
const [draft, setDraft] = useLocalStorage({
key: 'contact-form-draft',
defaultValue: { name: '', email: '', message: '' }
});
// Temporary form state for current session
const [errors, setErrors] = useSessionStorage({
key: 'contact-form-errors',
defaultValue: {}
});
const handleSubmit = () => {
// Clear draft after successful submission
setDraft({ name: '', email: '', message: '' });
setErrors({});
};
return (
<form onSubmit={handleSubmit}>
<input
value={draft.name}
onChange={(e) => setDraft(prev => ({ ...prev, name: e.target.value }))}
/>
{/* More form fields */}
</form>
);
}import { useLocalStorage } from "@mantine/hooks";
function useUserPreferences() {
const [preferences, setPreferences] = useLocalStorage({
key: 'user-preferences',
defaultValue: {
theme: 'light',
language: 'en',
notifications: true,
autoSave: true
},
sync: true // Sync across all open tabs
});
const updatePreference = (key: keyof typeof preferences, value: any) => {
setPreferences(prev => ({ ...prev, [key]: value }));
};
return { preferences, updatePreference, setPreferences };
}import { useLocalStorage } from "@mantine/hooks";
function useAuth() {
const [token, setToken, removeToken] = useLocalStorage({
key: 'auth-token',
defaultValue: '',
getInitialValueInEffect: true // Prevent SSR hydration issues
});
const [user, setUser] = useLocalStorage({
key: 'user-data',
defaultValue: null,
serialize: JSON.stringify,
deserialize: (str) => str ? JSON.parse(str) : null
});
const login = (newToken: string, userData: any) => {
setToken(newToken);
setUser(userData);
};
const logout = () => {
removeToken();
setUser(null);
};
return { token, user, login, logout, isAuthenticated: !!token };
}Both hooks support custom serialization for complex data types:
// Date serialization
const [lastVisit, setLastVisit] = useLocalStorage({
key: 'last-visit',
defaultValue: new Date(),
serialize: (date) => date.toISOString(),
deserialize: (str) => str ? new Date(str) : new Date()
});
// Complex object with methods
const [calculator, setCalculator] = useLocalStorage({
key: 'calculator-state',
defaultValue: { value: 0, history: [] },
serialize: JSON.stringify,
deserialize: (str) => {
if (!str) return { value: 0, history: [] };
const parsed = JSON.parse(str);
return {
...parsed,
// Restore methods if needed
calculate: () => { /* logic */ }
};
}
});// Prevent hydration mismatches in Next.js/other SSR frameworks
const [clientOnlyState, setClientOnlyState] = useLocalStorage({
key: 'client-state',
defaultValue: null,
getInitialValueInEffect: true // Only read from storage after hydration
});
// Use with conditional rendering
{clientOnlyState && <ClientOnlyComponent state={clientOnlyState} />}