Search
  • Sotiris Karapostolou

Using Local Storage in React-Native with Your Own Custom useAsyncStorage() Hook



What is a React Native Async Storage?

AsyncStorage is React Native's API for storing data persistently over the device. It's a storage system that we developers can use and save data in the form of key-value pairs.

AsyncStorage API is Asynchronous , so each of its methods returns a Promise object and in case of error, an Error object.


The package we need is:

yarn add @react-native-async-storage/async-storage"
// Can find the documentation here

What is a Custom Hook?

Based on the React documentation a custom hook allows you to extract some components logic into a reusable function. A custom hook is a Javascript function that starts with use and that call can other hooks. Remember that components and hooks are functions, so we are really not creating any new concepts here. We are just refactoring our code into another function to make it reusable.



Let's start with building our Hook!


  • Provide a local storage key and a default value. Local storage works off of key-value pairs, so we’ll want to be able to provide a key for our stored data and an initial value. If there’s no existing data in local storage under the provided key, we’ll want to be able to provide a defualtValue for our data.


#utils/useAsyncStorage.js
import React from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
export function useAsyncStorage(key, initialValue) {} 

  • On mount, we read the value at key and save it to the state under storedValue.


export function useAsyncStorage(key, initialValue) {
 const [storedValue, setStoredValue] = React.useState(initialValue);
 
 React.useEffect(() => {
 AsyncStorage.getItem(key)
      .then((value) => {
 if (value === null) return initialValue ? initialValue : null;
 return JSON.parse(value);
      })
      .then(setStoredValue);
  }, []);
  
}
  • Almost done! We still have one outstanding requirement we haven’t met yet: we need to save any data back to localStorage when it’s changed. I like doing this in a seperate function setValue, a new string gets generated, saved to async storage, and to the state.

	
export function useAsyncStorage(key, initialValue) {
 ....

 const setValue = (value) => {
 const valueToStore = value instanceof Function ? value(storedValue) : value;
 setStoredValue(valueToStore);
 AsyncStorage.setItem(key, JSON.stringify(valueToStore));
  };
}

	
  • Expose the state variable and a setter. Much like the useState hook, our useAsyncStorage hook will return a 2-element array. The first element will be the variable and the second will be a setter for that variable.

export function useAsyncStorage(key, initialValue) {
 const [storedValue, setStoredValue] = React.useState(initialValue);
 React.useEffect(() => {
 AsyncStorage.getItem(key)
      .then((value) => {
 if (value === null) return initialValue ? initialValue : null;
 return JSON.parse(value);
      })
      .then(setStoredValue);
  }, [key, initialValue]);

 const setValue = (value) => {
 const valueToStore = value instanceof Function ? value(storedValue) : value;
 setStoredValue(valueToStore);
 AsyncStorage.setItem(key, JSON.stringify(valueToStore));
  };

 return [storedValue, setValue];
}



Testing Out Our New Hook:
#App.js
import { useAsyncStorage } from 'utils/useAsyncStorage';

export const App = (props) => {
  const [theme, setTheme] = useAsyncStorage('::theme', 'dark');
  return (
     <View>
      <Text>Current Theme: {theme}</Text>
      <TouchableOpacity
 onPress={setTheme.bind(this, theme === 'light' ? 'dark' : 'light')}
 >
        <Text>Update Theme</Text>
      </TouchableOpacity>
    </View>
  );
};

Well, I hope that helped! Right to the point! If you like this and want to support me on making more stories you can contact me on Linkedin


#react #reactNative #hooks #customHooks #AsyncStorage

13 views0 comments