Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
React hook for Localforage (flow)
// @flow
// LocalForage: https://github.com/localForage/localForage
// npm i -S localForage
/**
* @author Junaid Atari <mj.atari@gmail.com>
* @link https://github.com/blacksmoke26
* @since 2020-08-05
*/
import React from 'react';
import localforage from 'localforage';
type HookMethods = [
any,
( value: any ) => void,
() => void,
];
/**
* React custom hook to save/restore value from localStorage using localforage library
* @example
* ```js
* function App() {
* const [value, set, remove] = useLocalForge('my-key', {});
* }
* ```
*/
export default function useLocalForge ( key: string, initialValue?: any ): HookMethods {
const [storedValue, setStoredValue] = React.useState(initialValue);
React.useEffect(() => {
(async function () {
try {
const value = await localforage.getItem(key);
setStoredValue(value);
} catch ( err ) {
return initialValue;
}
})();
}, [initialValue, storedValue, key]);
/** Set value */
const set = ( value: any ) => {
(async function () {
try {
await localforage.setItem(key, value);
setStoredValue(value);
} catch (err) {
return initialValue;
}
})();
};
/** Removes value from local storage */
const remove = () => {
(async function () {
try {
await localforage.removeItem(key);
setStoredValue(null);
} catch (e) {}
})();
};
return [storedValue, set, remove];
}
@blacksmoke26

This comment has been minimized.

Copy link
Owner Author

@blacksmoke26 blacksmoke26 commented Sep 20, 2020

Vanilla JS version:

/**
 * @author Junaid Atari <mj.atari@gmail.com>
 * @link https://github.com/blacksmoke26
 * @since 2020-08-05
 */

// LocalForage: https://github.com/localForage/localForage
// npm i -S localForage

import React from 'react';
import localforage from 'localforage';

/**
 * React custom hook to save/restore value from localStorage using localforage library
 * @example
 * ```js
 * function App() {
 *  const [value, set, remove] = useLocalForge('my-key', {});
 * }
 * ```
 * @param {string} key - Unique storage key
 * @param {*} initialValue=null - Initial value
 * @returns {[any, (function(any): void), (function(): void)]}
 */
export default function useLocalForge ( key, initialValue = null ) {
	const [storedValue, setStoredValue] = React.useState(initialValue);
	
	React.useEffect(() => {
		(async function () {
			try {
				const value = await localforage.getItem(key);
				setStoredValue(value);
			} catch ( err ) {
				return initialValue;
			}
		})();
	}, [initialValue, storedValue, key]);
	
	/** Set value */
	const set = ( value ) => {
		(async function () {
			try {
				await localforage.setItem(key, value);
				setStoredValue(value);
			} catch (err) {
				return initialValue;
			}
		})();
	};
	
	/** Removes value from local storage */
	const remove = () => {
		(async function () {
			try {
				await localforage.removeItem(key);
				setStoredValue(null);
			} catch (e) {}
		})();
	};
	
	return [storedValue, set, remove];
}
@ckeeney

This comment has been minimized.

Copy link

@ckeeney ckeeney commented Apr 6, 2021

It seems that if storedValue is an object, this causes a render loop since storedValue is a dependency of the useEffect hook.

@blacksmoke26

This comment has been minimized.

Copy link
Owner Author

@blacksmoke26 blacksmoke26 commented Jun 28, 2021

I will check it! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment