This is my take on a persistent state hook. The interface is similar to useState
and I prefixed the local storage key with use-persistent-state-
to prevent issues with duplicate keys.
Did you know that keys in local storage can be as big as you want? Of course the 5MB storage limit per domain still applies.
Usage
const [dismissed setDismissed] = usePersistentState('my-infobox', false);
Javascript
import { useState, useEffect } from 'react';
export function usePersistentState(key, initialState) {
const prefixedKey = 'use-persistent-state-' + key
// read key from local storage if not found use default value
const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(prefixedKey);
if (storedValue === null) {
if (typeof initialState === 'function') {
return initialState();
} else {
return initialState;
}
} else {
return JSON.parse(storedValue);
}
});
// update local storage when value changes
useEffect(() => {
localStorage.setItem(prefixedKey, JSON.stringify(value));
}, [value, prefixedKey]);
return [value, setValue];
}
Typescript
import { useState, useEffect } from 'react';
export function usePersistentState<Type>(key: string, initialState: Type | (() => Type)): [Type, React.Dispatch<React.SetStateAction<Type>>] {
const prefixedKey = 'use-persistent-state-' + key
// read key from local storage if not found use default value
const [value, setValue] = useState<Type>(() => {
const storedValue = localStorage.getItem(prefixedKey);
if (storedValue === null) {
if (typeof initialState === 'function') {
return (initialState as () => Type)();
} else {
return initialState;
}
} else {
return JSON.parse(storedValue);
}
});
// update local storage when value changes
useEffect(() => {
localStorage.setItem(prefixedKey, JSON.stringify(value));
}, [value, prefixedKey]);
return [value, setValue];
}
There is a discussion for the Type of initialState
here on StackOverflow:
Libraries
Here are some libraries and resources I found on the internet regarding this topic:
use-persisted-state by Donavon West
- popular
- no typescript
- seems abandoned
https://github.com/donavon/use-persisted-state#readme
https://www.npmjs.com/package/use-persisted-state
use-persistent-state by Krombik
- very new and not a lot of users
- typescript support
- author also had SSR in mind
- Did not try it yet
https://github.com/Krombik/use-persistent-state
https://www.npmjs.com/package/use-persistent-state
More
And there is also an implementation with some discussion here:
https://gist.github.com/gragland/2970ae543df237a07be1dbbf810f23fe
If you find more resources regarding this topic feel free to drop a comment below, thanks!
Top comments (0)