Paramclasses Academy - Blog

Tutorials Details

←
Post 23 of 39
→

How to use Local Data Storage in React Native Using AsyncStorage ?

How to use Local Data Storage in React Native Using AsyncStorage ?

November 5, 2026

1. Introduction

Every modern mobile application needs a way to store information.

For example:

  • A student management app stores student records.

  • A shopping app stores cart information.

  • A notes app stores personal notes.

  • A settings screen stores the user's preferred theme.

  • A task management app stores pending and completed tasks.

If information is stored only in React state, it will normally disappear when the application is closed and restarted.

To solve this problem, React Native applications can use local storage libraries such as AsyncStorage.

In this tutorial, we will learn how to store, retrieve, update and delete information locally using AsyncStorage.

We will build a practical Student Management App that saves student records on the device and restores them when the application opens again.

2. What Is Local Data Storage?

Local data storage means saving information directly on a user's device instead of sending every piece of information to a remote server.

For example:

Suppose a student enters the following information:

  • Name: Rahul Sharma

  • Email: rahul@gmail.com

  • Course: React Native

The application can save these details locally.

When the application is reopened, it can retrieve the saved information and display it again.

Advantages of Local Storage

  1. Data can remain available after application restarts.

  2. Some application features can work without internet access.

  3. Frequently used information can be retrieved without an API request.

  4. User preferences can be saved.

  5. Local caching can improve the user experience.

3. What Is AsyncStorage?

AsyncStorage is an asynchronous, persistent, key-value storage solution for React Native.

It allows an application to save and retrieve small amounts of information on a device.

Important characteristics:

  • Asynchronous operations.

  • Persistent key-value storage.

  • Stores string values.

  • Supports Android and iOS.

  • Supports Expo applications.

  • Does not require an internet connection for ordinary local storage operations.

Important: AsyncStorage is not built into the React Native core. We install it as a separate community-maintained package.

Its contents are unencrypted, so it should not be used as a secure vault for passwords, private keys or sensitive authentication secrets.

4. How Does AsyncStorage Work?

AsyncStorage works with two important concepts:

Key: A unique name used to identify stored information.

Value: The information saved under that key.

Example:

await AsyncStorage.setItem(
  "studentName",
  "Rahul Sharma"
);

Here:

  • studentName is the key.

  • Rahul Sharma is the value.

To retrieve the value:

const name = await AsyncStorage.getItem(
  "studentName"
);

console.log(name);

Output:

Rahul Sharma

Think of AsyncStorage as a small key-value storage system inside your mobile application.

5. Important AsyncStorage Methods

Method Purpose
setItem() Save information
getItem() Retrieve information
removeItem() Delete a specific key
clear() Clear the storage used by the app
getAllKeys() Retrieve stored keys
multiSet() Save multiple key-value pairs
multiGet() Retrieve multiple key-value pairs
multiRemove() Remove multiple keys

These methods are asynchronous and return Promises.

Therefore, we commonly use async and await.

6. Create a React Native Project

Open your terminal.

Create a new Expo project:

npx create-expo-app@latest StudentStorageApp --template blank

Open the project folder:

cd StudentStorageApp

Open Visual Studio Code:

code .

Start the development server:

npx expo start

Run your application using Expo Go or an Android emulator.

7. Install AsyncStorage

Now we need to install the AsyncStorage package.

Execute this command inside the project directory:

npx expo install @react-native-async-storage/async-storage

Why use npx expo install?

Expo selects a package version compatible with the installed Expo SDK.

After installation, we can import AsyncStorage into our application.

import AsyncStorage from
  "@react-native-async-storage/async-storage";

8. Save Data Using setItem()

Let's understand how to save a simple value.

Example:

const saveStudentName = async () => {

  try {

    await AsyncStorage.setItem(
      "studentName",
      "Rahul Sharma"
    );

    console.log("Student name saved successfully");

  } catch (error) {

    console.log("Error saving data", error);

  }

};

Explanation:

  1. async allows asynchronous operations.

  2. setItem() saves a value using a key.

  3. await waits for the storage operation to complete.

  4. try/catch handles storage errors.

9. Retrieve Data Using getItem()

We can retrieve previously saved information using getItem().

Example:

const getStudentName = async () => {

  try {

    const name = await AsyncStorage.getItem(
      "studentName"
    );

    console.log(name);

  } catch (error) {

    console.log("Error retrieving data", error);

  }

};

If the key exists, the saved value is returned.

If the key does not exist, AsyncStorage returns null.

10. Delete Data Using removeItem()

To delete a particular saved value, use removeItem().

Example:

const deleteStudentName = async () => {

  try {

    await AsyncStorage.removeItem(
      "studentName"
    );

    console.log("Student name deleted");

  } catch (error) {

    console.log("Error deleting data", error);

  }

};

This removes the specified key and its associated value.

11. Store Objects and Arrays Using JSON.stringify()

AsyncStorage stores string values.

But what if we want to save a complete student object?

Example:

const student = {

  id: 1,

  name: "Rahul Sharma",

  email: "rahul@gmail.com",

  course: "React Native"

};

We cannot directly store this JavaScript object using setItem().

We first need to convert it into a JSON string.

const jsonData = JSON.stringify(student);

Now save it:

await AsyncStorage.setItem(
  "student",
  jsonData
);

This is how we save objects and arrays in AsyncStorage.

12. Retrieve Objects Using JSON.parse()

When retrieving an object, we receive a string.

We must convert it back into a JavaScript object.

Example:

const jsonData = await AsyncStorage.getItem(
  "student"
);

if (jsonData !== null) {

  const student = JSON.parse(jsonData);

  console.log(student.name);

}

Output:

Rahul Sharma

Remember:

  • JSON.stringify() converts an object into a JSON string.

  • JSON.parse() converts JSON text back into a JavaScript value.

13. Practical Project: Student Management App

Now we will create a complete application using AsyncStorage.

Our application will support:

  1. Add a new student.

  2. Save student details locally.

  3. Retrieve previously saved students.

  4. Display all students.

  5. Delete a student.

  6. Keep records available after restarting the application.

Step 1: Import Components

Open App.js and add:

import React, { useEffect, useState } from "react";

import {
  View,
  Text,
  TextInput,
  Pressable,
  FlatList,
  StyleSheet,
  Alert,
  ActivityIndicator,
} from "react-native";

import AsyncStorage from
  "@react-native-async-storage/async-storage";

Step 2: Create State Variables

Inside the App component:

const [name, setName] = useState("");

const [email, setEmail] = useState("");

const [course, setCourse] = useState("");

const [students, setStudents] = useState([]);

const [loading, setLoading] = useState(true);

Explanation:

  • name stores the student's name.

  • email stores the student's email.

  • course stores the course name.

  • students stores all student records.

  • loading manages the initial storage loading process.

Step 3: Create a Function to Load Students

const loadStudents = async () => {

  try {

    const storedData = await AsyncStorage.getItem(
      "students"
    );

    if (storedData !== null) {

      const parsedData = JSON.parse(storedData);

      if (Array.isArray(parsedData)) {
        setStudents(parsedData);
      } else {
        setStudents([]);
      }

    }

  } catch (error) {

    console.log("Error loading students", error);

  } finally {

    setLoading(false);

  }

};

Explanation:

  1. Retrieve the saved data using getItem().

  2. Check whether data exists.

  3. Convert the JSON string into an array.

  4. Update the students state.

  5. Stop the loading indicator.

Step 4: Load Data When the App Opens

We want previously saved student records to appear automatically when the application starts.

Use useEffect():

useEffect(() => {

  loadStudents();

}, []);

The empty dependency array ensures the initial loading function is triggered when the component mounts.

Step 5: Create a Save Function

Now create a function to add a new student.

const addStudent = async () => {

  if (!name.trim() ||
      !email.trim() ||
      !course.trim()) {

    Alert.alert(
      "Error",
      "Please fill all fields"
    );

    return;

  }

  const newStudent = {

    id: Date.now().toString(),

    name: name.trim(),

    email: email.trim(),

    course: course.trim()

  };

  const updatedStudents = [
    ...students,
    newStudent
  ];

  try {

    await AsyncStorage.setItem(
      "students",
      JSON.stringify(updatedStudents)
    );

    setStudents(updatedStudents);

    setName("");
    setEmail("");
    setCourse("");

    Alert.alert(
      "Success",
      "Student saved successfully"
    );

  } catch (error) {

    Alert.alert(
      "Error",
      "Unable to save student"
    );

  }

};

Explanation:

  • Validate the input fields.

  • Create a new student object.

  • Add the object to the existing student array.

  • Convert the updated array into JSON.

  • Save it using setItem().

  • Update the application state.

Notice that we save the data before updating the UI state. This helps prevent showing a successful update when storage fails.

Step 6: Create a Delete Function

Now we will delete a student record.

const deleteStudent = async (id) => {

  const updatedStudents = students.filter(
    student => student.id !== id
  );

  try {

    await AsyncStorage.setItem(
      "students",
      JSON.stringify(updatedStudents)
    );

    setStudents(updatedStudents);

    Alert.alert(
      "Success",
      "Student deleted successfully"
    );

  } catch (error) {

    Alert.alert(
      "Error",
      "Unable to delete student"
    );

  }

};

Explanation:

  • filter() selects all students except the one being deleted.

  • The updated array is converted into JSON.

  • AsyncStorage saves the updated records.

  • The UI displays the updated list.

Step 7: Display Students Using FlatList

We will display all saved students using FlatList.

<FlatList

  data={students}

  keyExtractor={(item) => item.id}

  renderItem={({ item }) => (

    <View style={styles.card}>

      <Text style={styles.name}>
        {item.name}
      </Text>

      <Text>
        {item.email}
      </Text>

      <Text>
        Course: {item.course}
      </Text>

      <Pressable
        style={styles.deleteButton}
        onPress={() => deleteStudent(item.id)}
      >

        <Text style={styles.buttonText}>
          Delete
        </Text>

      </Pressable>

    </View>

  )}

  ListEmptyComponent={
    <Text style={styles.empty}>
      No students saved yet.
    </Text>
  }

/>

Step 8: Create the Student Form

Add these components to your screen:

<TextInput
  style={styles.input}
  placeholder="Enter student name"
  value={name}
  onChangeText={setName}
/>

<TextInput
  style={styles.input}
  placeholder="Enter email"
  value={email}
  onChangeText={setEmail}
  keyboardType="email-address"
  autoCapitalize="none"
/>

<TextInput
  style={styles.input}
  placeholder="Enter course"
  value={course}
  onChangeText={setCourse}
/>

<Pressable
  style={styles.saveButton}
  onPress={addStudent}
>

  <Text style={styles.buttonText}>
    Save Student
  </Text>

</Pressable>

These input fields allow users to enter student information.

14. Complete Student Management App Code

Now replace your entire App.js file with the following code.

import React, { useEffect, useState } from "react";

import {
  View,
  Text,
  TextInput,
  Pressable,
  FlatList,
  StyleSheet,
  Alert,
  ActivityIndicator,
} from "react-native";

import AsyncStorage from
  "@react-native-async-storage/async-storage";

export default function App() {

  const [name, setName] = useState("");

  const [email, setEmail] = useState("");

  const [course, setCourse] = useState("");

  const [students, setStudents] = useState([]);

  const [loading, setLoading] = useState(true);

  const loadStudents = async () => {

    try {

      const storedData = await AsyncStorage.getItem(
        "students"
      );

      if (storedData !== null) {

        const parsedData = JSON.parse(storedData);

        if (Array.isArray(parsedData)) {
          setStudents(parsedData);
        }

      }

    } catch (error) {

      console.log("Loading error:", error);

      Alert.alert(
        "Error",
        "Unable to load saved students"
      );

    } finally {

      setLoading(false);

    }

  };

  useEffect(() => {

    loadStudents();

  }, []);

  const addStudent = async () => {

    if (
      !name.trim() ||
      !email.trim() ||
      !course.trim()
    ) {

      Alert.alert(
        "Error",
        "Please fill all fields"
      );

      return;

    }

    const newStudent = {

      id: Date.now().toString(),

      name: name.trim(),

      email: email.trim(),

      course: course.trim()

    };

    const updatedStudents = [
      ...students,
      newStudent
    ];

    try {

      await AsyncStorage.setItem(
        "students",
        JSON.stringify(updatedStudents)
      );

      setStudents(updatedStudents);

      setName("");
      setEmail("");
      setCourse("");

      Alert.alert(
        "Success",
        "Student saved successfully"
      );

    } catch (error) {

      Alert.alert(
        "Error",
        "Unable to save student"
      );

    }

  };

  const deleteStudent = async (id) => {

    const updatedStudents = students.filter(
      student => student.id !== id
    );

    try {

      await AsyncStorage.setItem(
        "students",
        JSON.stringify(updatedStudents)
      );

      setStudents(updatedStudents);

      Alert.alert(
        "Success",
        "Student deleted successfully"
      );

    } catch (error) {

      Alert.alert(
        "Error",
        "Unable to delete student"
      );

    }

  };

  if (loading) {

    return (

      <View style={styles.center}>

        <ActivityIndicator
          size="large"
          color="#2563EB"
        />

        <Text>
          Loading saved students...
        </Text>

      </View>

    );

  }

  return (

    <View style={styles.container}>

      <Text style={styles.heading}>
        Student Management App
      </Text>

      <Text style={styles.subtitle}>
        Local Storage Using AsyncStorage
      </Text>

      <TextInput
        style={styles.input}
        placeholder="Enter student name"
        value={name}
        onChangeText={setName}
      />

      <TextInput
        style={styles.input}
        placeholder="Enter email"
        value={email}
        onChangeText={setEmail}
        keyboardType="email-address"
        autoCapitalize="none"
      />

      <TextInput
        style={styles.input}
        placeholder="Enter course"
        value={course}
        onChangeText={setCourse}
      />

      <Pressable
        style={styles.saveButton}
        onPress={addStudent}
      >

        <Text style={styles.buttonText}>
          Save Student
        </Text>

      </Pressable>

      <Text style={styles.listHeading}>
        Saved Students ({students.length})
      </Text>

      <FlatList

        data={students}

        keyExtractor={(item) => item.id}

        renderItem={({ item }) => (

          <View style={styles.card}>

            <Text style={styles.name}>
              {item.name}
            </Text>

            <Text style={styles.info}>
              Email: {item.email}
            </Text>

            <Text style={styles.info}>
              Course: {item.course}
            </Text>

            <Pressable
              style={styles.deleteButton}
              onPress={() => deleteStudent(item.id)}
            >

              <Text style={styles.buttonText}>
                Delete Student
              </Text>

            </Pressable>

          </View>

        )}

        ListEmptyComponent={

          <Text style={styles.empty}>
            No students saved yet.
          </Text>

        }

      />

    </View>

  );

}

const styles = StyleSheet.create({

  container: {
    flex: 1,
    backgroundColor: "#F1F5F9",
    padding: 20,
    paddingTop: 55,
  },

  center: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    gap: 12,
  },

  heading: {
    fontSize: 23,
    fontWeight: "bold",
    color: "#1E293B",
  },

  subtitle: {
    fontSize: 13,
    color: "#64748B",
    marginBottom: 20,
  },

  input: {
    backgroundColor: "#FFFFFF",
    padding: 14,
    borderRadius: 10,
    marginBottom: 12,
    borderWidth: 1,
    borderColor: "#CBD5E1",
  },

  saveButton: {
    backgroundColor: "#2563EB",
    padding: 15,
    borderRadius: 10,
    alignItems: "center",
    marginBottom: 20,
  },

  buttonText: {
    color: "#FFFFFF",
    fontWeight: "bold",
  },

  listHeading: {
    fontSize: 19,
    fontWeight: "bold",
    marginBottom: 12,
    color: "#1E293B",
  },

  card: {
    backgroundColor: "#FFFFFF",
    padding: 16,
    marginBottom: 12,
    borderRadius: 12,
    elevation: 3,
  },

  name: {
    fontSize: 18,
    fontWeight: "bold",
    color: "#2563EB",
    marginBottom: 8,
  },

  info: {
    fontSize: 14,
    color: "#475569",
    marginBottom: 5,
  },

  deleteButton: {
    backgroundColor: "#DC2626",
    padding: 11,
    borderRadius: 8,
    alignItems: "center",
    marginTop: 12,
  },

  empty: {
    textAlign: "center",
    color: "#64748B",
    marginTop: 20,
  },

});

15. Test the Application

Now run your application.

Follow these steps:

Test 1: Add a student

Enter:

  • Name: Rahul Sharma

  • Email: rahul@gmail.com

  • Course: React Native

Press Save Student.

The student should appear in the list.

Test 2: Add another student

Enter:

  • Name: Amit Kumar

  • Email: amit@gmail.com

  • Course: JavaScript

Save the second record.

Both records should appear.

Test 3: Restart the application

Close the application completely and open it again.

The previously saved students should still appear.

Test 4: Delete a student

Press Delete Student on Rahul Sharma's card.

The selected record should disappear.

Test 5: Restart again

Close and reopen the application.

The deleted record should remain deleted because the updated array was saved in AsyncStorage.

16. Other Useful AsyncStorage Operations

A. Retrieve All Stored Keys

const getStorageKeys = async () => {

  try {

    const keys = await AsyncStorage.getAllKeys();

    console.log(keys);

  } catch (error) {

    console.log(error);

  }

};

B. Remove a Specific Key

await AsyncStorage.removeItem("students");

C. Clear Application Storage

await AsyncStorage.clear();

Warning: clear() removes all AsyncStorage entries for the application, including data saved by other features using the same storage. Prefer removeItem() when you only need to delete one feature's data.

D. Save Multiple Values

await AsyncStorage.multiSet([

  ["studentName", "Rahul"],

  ["studentCourse", "React Native"],

  ["studentCity", "Raipur"]

]);

E. Retrieve Multiple Values

const data = await AsyncStorage.multiGet([

  "studentName",

  "studentCourse",

  "studentCity"

]);

console.log(data);

17. AsyncStorage vs Database

AsyncStorage is useful for small amounts of key-value information, but it is not a replacement for a full database.

Feature AsyncStorage SQLite
Storage type Key-value Relational database
Data format Strings Tables and columns
SQL queries No Yes
Small preferences Excellent Possible
Complex relationships Not suitable Suitable
Large structured datasets Limited More appropriate

For more complex local data management, Expo SQLite is another option.

18. Important Limitations and Security

Before using AsyncStorage in a production application, understand these points:

  1. Data is unencrypted.

  2. Storage is intended for relatively small amounts of information.

  3. It is asynchronous, so operations should use proper Promise handling.

  4. Data generally remains available across app restarts.

  5. Uninstalling the application normally removes its local application data.

  6. It does not automatically synchronize information with a server.

  7. It should not be treated as a database for large relational datasets.

For sensitive information, use an appropriate secure storage solution. In Expo projects, expo-secure-store is an option for small secrets such as tokens, subject to its platform and storage limitations.

19. Common Errors and Solutions

Error 1: Cannot find module AsyncStorage

Reason: The package is not installed.

Solution:

npx expo install @react-native-async-storage/async-storage

Error 2: Data is not appearing after restart

Possible reasons:

  • Incorrect storage key.

  • JSON parsing error.

  • Data was never successfully saved.

  • The loading function was not called.

Solution: Check the storage key and inspect the saved JSON data.

Error 3: JSON Parse Error

Reason: Stored information is not valid JSON.

Solution: Use try/catch around JSON.parse() and validate the retrieved data.

Error 4: Data is not updating

Reason: Only the React state was changed, but the updated data was not saved to AsyncStorage.

Solution: Save the updated array using setItem().

Error 5: Data is not deleted

Reason: The wrong key or an incorrect updated array was used.

Solution: Check the key and save the filtered array after deleting a record.

20. Practical Exercises

Complete these exercises:

  1. Save a student's name using setItem().

  2. Retrieve the name using getItem().

  3. Delete the saved name using removeItem().

  4. Save a student object using JSON.stringify().

  5. Retrieve the student object using JSON.parse().

  6. Save multiple student records in an array.

  7. Display records using FlatList.

  8. Add a delete button for every record.

  9. Restart the app and verify persistence.

  10. Add an Update Student feature.

21. Conclusion

In this tutorial, we learned how to store information locally in React Native using AsyncStorage.

We covered:

  • Local data storage.

  • AsyncStorage fundamentals.

  • Installing AsyncStorage.

  • setItem().

  • getItem().

  • removeItem().

  • JSON.stringify().

  • JSON.parse().

  • Saving arrays and objects.

  • Loading data with useEffect().

  • Displaying saved records using FlatList.

  • Adding and deleting student records.

  • Storage limitations and security.

We also built a practical Student Management Application that saves student records on the device and retrieves them after application restarts.

AsyncStorage is an important concept when building mobile applications that need persistent local information.

22. Frequently Asked Questions

Q1. What is AsyncStorage in React Native?

AsyncStorage is an asynchronous key-value storage library used to save persistent information locally on a device.

Q2. Is AsyncStorage built into React Native?

No. It is maintained as a separate community package.

Q3. Do we need internet to use AsyncStorage?

No. Ordinary AsyncStorage operations work locally without an internet connection.

Q4. Does AsyncStorage store objects directly?

No. It stores strings. Convert objects and arrays using JSON.stringify() before saving.

Q5. What is getItem()?

It retrieves a previously stored value using its key.

Q6. What is setItem()?

It saves a string value under a specified key.

Q7. Will data remain after closing the application?

Yes. AsyncStorage is persistent and normally retains data after an application restart.

Q8. Is AsyncStorage secure for passwords?

No. Its data is unencrypted. Use appropriate secure storage for sensitive information.

Q9. Can AsyncStorage store multiple student records?

Yes. Convert the student array into a JSON string and save it.

Q10. What is the difference between AsyncStorage and SQLite?

AsyncStorage is designed for key-value storage, while SQLite provides structured relational database storage with SQL queries.

←
Post 23 of 39
→