Skip to main content

useSessionStorage

Like useState but persisted on sessionStorage.

SSG/SSR-friendly.


API​

const [state, setState] = useSessionStorage({
key,
initialValue,
fallbackValue,
storageToStateFn,
});

Options​

  • key: string(Required)
    • The sessionStorage key
  • initialValue?: any (T)
    • Defaults to null
    • The initial value of the state
  • fallbackValue?: any (T)
    • Defaults to null
    • Will be used if there is no data stored in the sessionStorage (with the specified key)
  • storageToStateFn?: (state: T, { initialValue, fallbackValue }) => any
    • Function to re-map the data from the sessionStorage
    • You can add validation here, for example:
      (data, { initialValue }) => isExpired ? initialValue : data

Returns​

  • state: T (generic)
    • Just like useState
  • setState: SetStateAction
    • Just like useState

Examples​

Simple​

http://localhost:3000/
Count: 0
import { useSessionStorage } from 'react-power-ups';

type StorageData = {
value: number;
expiredAt: number;
};

export function DemoValidation() {
const [data, setData] = useSessionStorage<StorageData>({
key: 'my-counter-with-expiration',
initialValue: { value: 1, expiredAt: Date.now() + 30 * 1000 },
fallbackValue: { value: 1, expiredAt: Date.now() + 30 * 1000 },
storageToStateFn: (data, { fallbackValue }) => {
if (data.expiredAt > Date.now()) return data;
return fallbackValue;
},
});

return (
<>
<div>Count: {data.value}</div>
<div>Will expires in {Math.ceil((data.expiredAt - Date.now()) / 1000)}s</div>

<button onClick={() => setData((prev) => ({ ...prev, value: prev.value + 1 }))}>
Increment
</button>

<button onClick={() => window.location.reload()}>Reload window</button>
<button onClick={() => sessionStorage.setItem('my-counter-with-expiration', '123')}>
Set sessionStorage data to an invalid value
</button>
<button onClick={() => sessionStorage.clear()}>Clear sessionStorage</button>
</>
);
}

Code: https://github.com/afiiif/react-power-ups/blob/main/src/use-session-storage.ts