Web Development

How To Use React Native AsyncStorage

April 29th, 2022 | By Aman Mittal | 6 min read

AsyncStorage is simple, asynchronous, and unencrypted by default module that allows you to persist data offline in React Native apps. The persistence of data is done using a key-value storage system.

There are numerous scenarios where this module can be beneficial. Persisting data in a mobile app has benefits, such as the fact that when the user restarts the app, the data or setting variables are available to the user in the state they left before closing the app. This scenario is going to be covered in this tutorial.

Find the complete code for this tutorial at this GitHub repo.


A guide to React Native's AsyncStorage


Installing the community module

React Native version 0.60.0+ has lots of its API modules available as separate packages that you can easily install with a package manager such as npm or yarn. These packages are managed by community members and open-source developers.

To begin, let us create a new React Native project and install the module: @react-native-async-storage/async-storage. From a terminal window, execute the following commands in the order they are specified:

# create a new react-native app
npx react-native init rnAsyncStorageExample

# navigate inside the project directory
cd rnAsyncStorageExample

# install the async-storage module
yarn add @react-native-async-storage/async-storage

# Or is you prefer to use npm
npm install @react-native-async-storage/async-storage


If you are using the latest React Native version (0.60.x or above), you do not have to link the native binaries for iOS and Android platforms manually. This linking of the module is handled automatically by the CLI. Though, for iOS, you have to install Cocoapods. Go back to the terminal window and execute the following command:

npx pod-install ios


That's it in terms of configuring the AsyncStorage module to work in the React Native app.


Changing the default storage limitation on Android

On iOS devices, AsyncStorage is not limited programmatically. So, how to use asyncstorage in React Native?

On Android devices, by default, the current AsyncStorage size is set to 6MB. Reaching this limit is going to result in errors like the database or disk being full. There are valid reasons why this limit exists, but if there is a need to increase the size, you can do that. Open the android/gradle.properties file and add the following:

AsyncStorage_db_size_in_MB=10


This file represents any project-wise settings that you can use to override the default values or settings.

Now, to make sure everything is working correctly, build the Android app (and make sure an Android device or emulator is running before you execute the command below).

npx react-native run-android


You are going to get the default screen that confirms that the app is configured.
react-native-asyncstorage-app-1

Similarly, to build the app for iOS, execute the command below:

npx react-native run-ios



Using the AsyncStorage API

Let's start by creating an example. In this example application, you will save a value from the user's input in the storage and fetch the value from the storage. This reading and writing of data is going to be done with the help of AsyncStorage API functions.

Open the App.js file and start by importing the following components.

import React, {useState, useEffect} from 'react';
import {
  StyleSheet,
  View,
  Text,
  TextInput,
  TouchableOpacity,
} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';


Next, define a variable named STORAGE_KEY. It is used to read and save the data. You can think of this key as the identifier of the value that is being stored, hence, the key-value storage system. As you are going to store only one value at the moment, there is only one key required.

let STORAGE_KEY = '@user_input';


Inside the functional component App, define a state variable input that has an empty string as its default value.

const App = () => {
  const [input, setInput] = useState('');
  // ...
};

export default App;



Saving the data

To save the data for the app to read, let us define an asynchronous helper method called saveData. This method is going to be promise-based, which means you can use the async-await syntax with a try-catch block.

Passing the identifier STORAGE_KEY as well as the input state variable, the API method AsyncStorage.setItem is going to store the value in storage.

Let us update the state as well as display an alert box when the data is successfully stored.

const saveData = async () => {
  try {
    await AsyncStorage.setItem(STORAGE_KEY, age)
    alert('Data successfully saved')
  } catch (e) {
    alert('Failed to save the data to the storage')
  }
}const saveData = async () => {
  try {
    await AsyncStorage.setItem(STORAGE_KEY, age)
    alert('Data successfully saved')
  } catch (e) {
    alert('Failed to save the data to the storage')
  }
}


Reading the data

When the app restarts, it should be able to read the data that persisted in the previous section. For this, create another helper function called readData that is going to be asynchronous.

This function is going to read the value from the storage using the API method AsyncStorage.getItem and will only set the value of the state variable input when its value is not null.

const readData = async () => {
  try {
    const value = await AsyncStorage.getItem(STORAGE_KEY);

    if (value !== null) {
      setInput(value);
    }
  } catch (e) {
    alert('Failed to fetch the input from storage');
  }
};


To retrieve the data whenever the app starts, invoke this method inside the useEffect hook.

useEffect(() => {
  readData();
}, []);


Clearing all storage

Another API method that the current demo app is going to utilize from the AsyncStorage API is called clear. This method deletes everything that was previously saved.

If you want to delete only a specific item from the storage, there are other methods available such as removeItem or multiRemove by the AsyncStorage API.

Add the following snippet:

const clearStorage = async () => {
  try {
    await AsyncStorage.clear();
    alert('Storage successfully cleared!');
  } catch (e) {
    alert('Failed to clear the async storage.');
  }
};



Controlling the input

The last two helper functions this example app requires are onChangeText and onSubmitEditing.

These methods are going to be responsible for reading the input and updating the state variable as well as storing the input.

const onChangeText = value => setInput(value);

const onSubmitEditing = () => {
  if (!input) return;

  saveData(input);
  setInput('');
};



Completing the app

We have defined all the helper functions that are required by the app. Let us complete the return statement by defining the JSX as below:

const App = () => {
  // ... rest of the code remains the same

  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.title}>AsyncStorage React Native</Text>
      </View>
      <View style={styles.panel}>
        <Text style={styles.label}>Enter your input here:</Text>
        <TextInput
          style={styles.inputField}
          value={input}
          placeholder="Enter"
          onChangeText={onChangeText}
          onSubmitEditing={onSubmitEditing}
        />
        <Text style={styles.text}>Your input is {input}</Text>
        <Pressable onPress={clearStorage} style={styles.button}>
          <Text style={styles.buttonText}>Clear Storage</Text>
        </Pressable>
      </View>
    </View>
  );
};


Here are the corresponding styles to the above code snippet:

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    width: '100%',
    backgroundColor: '#dcdcdc',
    paddingTop: 48,
    paddingBottom: 10,
    borderBottomWidth: StyleSheet.hairlineWidth,
    alignItems: 'center',
  },
  title: {
    fontSize: 22,
    color: '#333',
    fontWeight: 'bold',
  },
  panel: {
    paddingTop: 10,
    paddingHorizontal: 10,
  },
  label: {
    fontSize: 20,
  },
  text: {
    fontSize: 24,
    paddingTop: 10,
  },
  inputField: {
    backgroundColor: '#fff',
    height: 44,
    borderWidth: 1,
    borderColor: '#333',
    width: '100%',
    padding: 10,
    marginTop: 12,
  },
  button: {
    margin: 10,
    padding: 10,
    backgroundColor: 'orange',
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 4,
  },
  buttonText: {
    fontSize: 18,
    color: '#444',
  },
});


Now, go back to the iOS simulator, and you are going to be welcomed by the following screen:

asyncstorage-react-native-iOs-simulator-screen-with-welcome-message


Next, enter a value, close the app, and then open the app to see if the value was stored or not.
storing-a-new-value-in-the-app

Lastly, see what happens when you click on the "Clear Storage" button.


Conclusion: The use of AsyncStorage API in React Native app


Congratulations! I hope that, in this tutorial, you learned the basic API methods for using the AsyncStorage API in your React Native app. Even though the demo app was minimal, it allowed us to understand the concepts.

Explore the complete API for the AsyncStorage module, which you can refer to for further reading.

And speaking of further reading, don't miss our guide on React Native Security and our tutorial on protecting the source code of React Native apps against code tampering and reverse-engineering.


Jscrambler

The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.

View All Articles

Must read next

Web Development

How To Use Redux Persist in React Native with Asyncstorage

The Redux Persist library provides an easy way to save a Redux store in the local storage of React Native apps. In this post, we explore how to set it up.

January 8, 2021 | By Aman Mittal | 15 min read

Web Development

How to Set Up and Use Navigators in React Native

React Native navigators are used to quickly set up routing of screens. In this tutorial, we fetch data using GraphQL and then pass it between two screens.

July 17, 2020 | By Aman Mittal | 13 min read

Section Divider

Subscribe to Our Newsletter