React Native's AsyncStorage makes storing and persisting data in a React Native app simple. With the AsyncStorage API, you can handle simple cases of small data within your app without the need for the device's local storage or complex storage systems.

What Is React Native's AsyncStorage?

The AsyncStorage API is a persistent key-value storage system. The API supports a range of JavaScript data types, including string, boolean, number, and JSON objects.

The data stored using AsyncStorage persists and will remain available even if the app closes or the device restarts. This makes AsyncStorage an ideal storage solution for caching data and storing small amounts of application state.

What Problem Is AsyncStorage Solving?

Before the advent of AsyncStorage, proper data caching was an unreliable effort. You could either store data in local storage, which is unable to persist data when your app closes, or you could store the data in a Relational Database Management System (RDBMS). But they are too complex to operate for this use case.

AsyncStorage solves these problems by providing a simple, reliable way to store small and temporary data in React Native applications.

To store data with AsyncStorage, the data is first serialized into a JSON string. The JSON string is then stored in a key-value system. When you attempt to retrieve data from AsyncStorage, the data is deserialized from JSON and then returned to you in its original format.

These are asynchronous programs that run without blocking the main JavaScript thread. Making it ideal for storing data that needs frequent access, such as user settings and application state.

AsyncStorage Methods

To install the react-native-async-storage package, run the following command inside your project’s terminal:

        npm install @react-native-async-storage/async-storage

Since AsyncStorage is asynchronous in nature, its methods will not return results immediately. Instead, they return a promise that resolves when the operation is complete.

You should use the async/await syntax or a similar technique when calling AsyncStorage methods.

Write Data Using the setItem() and multiSet() Methods

The setItem() and multiSet() methods are used to set the values for the given key. These methods accept the key and the values as parameters.

The method would return a promise that resolves with a boolean value indicating whether the operation was successful or rejects with an error if the operation failed:

        // Save a value for the key "user"
await AsyncStorage.setItem('user', 'john');

// Save multiple values for the key "user"
await AsyncStorage.multiSet(['user', 'john', 'doe']);

Read Data Using the getItem() and multiGet() Methods

With the getItem() method, you can pull saved data from the storage using the key for the value you want to get. If the passed key does not exist, the promise rejects with an error:

        const name = await AsyncStorage.getItem('user');

The value returned by getItem() is a string. If you need to store data in another format, you can use JSON.stringify() to convert the data to a string before storing it. Then use JSON.parse() to convert the string back to the original data type when retrieving it.

For example:

        // Save the object {name: "John Doe", age: 30} for the key "user"
await AsyncStorage.setItem('user', JSON.stringify({name: "John Doe", age: 30}));

// Get the object for the key "user"
const user = JSON.parse(await AsyncStorage.getItem('user'));

You can also use the multiGet() method to pull multiple key-value pairs. The method will take an array of keys that must be strings.

Merge Data Using the mergeItem() and multiMerge() Methods

The mergeItem() and multiMerge() methods merge the given value with the existing value for the given key. The value passed to mergeItem() can be any type of data. However, it is important to note that AsyncStorage does not encrypt the data, so anyone with access to the device can read the data:

        await AsyncStorage.mergeItem('name', 'Jane Doe');

mergeItem() takes the key for the value you want to merge and the new value you want to merge with the existing value of the key. Use multiMerge() to merge more than one item to a key value.

Clear Storage Using the clear() Method

The clear() method allows you to remove all the items stored in AsyncStorage. It can be useful in various scenarios, such as when you need to reset the app's state during a user log-out or clear cached data on your mobile phone.

For example:

        const clearData = async () => {
  try {
    await AsyncStorage.clear();
 
  } catch (e) {
    console.error(e);
  }
};

The above code will delete all the key-value pairs stored in AsyncStorage.

Additionally, you can provide a callback function to clear(), which will be invoked once the operation is complete:

        AsyncStorage.clear()
  .then(() => {
    // Clear operation completed
   
  })
  .catch((error) => {
    console.error(error);
  });

Note that the clear() method will permanently delete all the data stored in AsyncStorage.

Caching Data With AsyncStorage

Caching data is a common practice in mobile app development to improve performance and reduce network requests. With AsyncStorage, you can easily cache data in React Native apps.

When you access a piece of data, the data is first checked to see if it is already in the cache. If it is, then the data is returned from the cache. If it is not, then the program retrieves the data from the more permanent storage location and stores it in the cache. The next time you access the data, it will be returned from the cache instead.

Assume that you have an app that displays a list of books fetched from an API. To enhance performance, you can cache the fetched book data using AsyncStorage.

Here's an example implementation of this:

        const [books, setBooks] = useState([]);

useEffect(() => {
    const fetchBooks = async () => {
      try {
        // Check if the cached data exists
        const cachedData = await AsyncStorage.getItem('cachedBooks');

        if (cachedData !== null) {
          // If the cached data exists, parse and set it as the initial state
          setBooks(JSON.parse(cachedData));
        } else {
          // If the cached data doesn't exist, fetch data from the API
          const response = await fetch('https://api.example.com/books');
          const data = await response.json();

          // Cache the fetched data
          await AsyncStorage.setItem('cachedBooks', JSON.stringify(data));

          // Set the fetched data as the initial state
          setBooks(data);
        }
      } catch (error) {
        console.error(error);
      }
    };

    fetchBooks();
  }, []);

In this example, you use the useEffect hook to fetch the book data. Within the fetchBooks function, check if the cached data exists by calling AsyncStorage.getItem('cachedBooks'). If the cached data exists, parse it using JSON.parse and set it as the initial state using setBooks. This allows you to display the cached data immediately.

If the cached data doesn't exist, fetch the data from the API using the fetch() method. Once the data is returned, cache it by calling AsyncStorage.setItem(). Then set the fetched data as the initial state, ensuring that further renders will display the fetched data.

You can now display the cached books like this:

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

const App = () => {
  return (
    <View>
      <Text>Book List</Text>
      <FlatList
        data={books}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => (
          <View>
            <Text>{item.title}</Text>
            <Text>{item.author}</Text>
          </View>
        )}
      />
    </View>
  );
};

export default App;

Further app launches or screen reloads will display the cached data without making unnecessary API requests.

Using AsyncStorage for Dynamic Data Loading

React Native AsyncStorage offers a powerful solution for storing and retrieving data. Leveraging caching capabilities, it enhances performance and provides faster access to stored data.

When you combine knowledge of AsyncStorage with techniques like custom pagination, you can dynamically load and display data in your React Native app. This will enable for efficient handling of large datasets.