usePersistedState
Returns a stateful value, persisted in localStorage, and a function to update it.
- Use the
useState()
hook to initialize thevalue
todefaultValue
. - Use the
useRef()
hook to create a ref that will hold thename
of the value inlocalStorage
. - Use 3 instances of the
useEffect()
hook for initialization,value
change andname
change respectively. - When the component is first mounted, use
Storage.getItem()
to updatevalue
if there's a stored value orStorage.setItem()
to persist the current value. - When
value
is updated, useStorage.setItem()
to store the new value. - When name is updated, use
Storage.setItem()
to create the new key, update thenameRef
and useStorage.removeItem()
to remove the previous key fromlocalStorage
. - NOTE: The hook is meant for use with primitive values (i.e. not objects) and doesn't account for changes to
localStorage
due to other code. Both of these issues can be easily handled (e.g. JSON serialization and handling the'storage'
event).
const usePersistedState = (name, defaultValue) => { const [value, setValue] = React.useState(defaultValue); const nameRef = React.useRef(name);
React.useEffect(() => { try { const storedValue = localStorage.getItem(name); if (storedValue !== null) setValue(storedValue); else localStorage.setItem(name, defaultValue); } catch { setValue(defaultValue); } }, []);
React.useEffect(() => { try { localStorage.setItem(nameRef.current, value); } catch {} }, [value]);
React.useEffect(() => { const lastName = nameRef.current; if (name !== lastName) { try { localStorage.setItem(name, value); nameRef.current = name; localStorage.removeItem(lastName); } catch {} } }, [name]);
return [value, setValue];};Examples;const MyComponent = ({ name }) => { const [val, setVal] = usePersistedState(name, 10); return ( <input value={val} onChange={(e) => { setVal(e.target.value); }} /> );};
const MyApp = () => { const [name, setName] = React.useState("my-value"); return ( <> <MyComponent name={name} /> <input value={name} onChange={(e) => { setName(e.target.value); }} /> </> );};
ReactDOM.render(<MyApp />, document.getElementById("root"));
Sign for comment
You can write your questions about the subject below.
LoginYour information is only used to display your name and reply by email.
- M.samet.28 Jun 2021 at 12:32 noonhi from react use-persisted-state