Working with Local Storage (AsyncStorage)
1. Installing AsyncStorage
| Step | Description | Notes |
|---|---|---|
| 1 | Install the package using npm or yarn | Ensure you have React Native CLI or Expo CLI set up |
| 2 | Import the library in your component | Use import AsyncStorage from '@react-native-async-storage/async-storage' |
2. Storing String Data
| Method | Description | Parameters | Return Type |
|---|---|---|---|
| setItem | Stores a string value for a given key | key: string, value: string |
Promise<void> |
Example: Storing a String Value
import AsyncStorage from '@react-native-async-storage/async-storage';
const storeString = async () => {
try {
await AsyncStorage.setItem('userToken', 'abc123');
console.log('String stored successfully');
} catch (error) {
console.error('Error storing string:', error);
}
};
storeString();
3. Retrieving Data
| Method | Description | Return Type | Notes |
|---|---|---|---|
| getItem(key) | Retrieves the value for a given key | Promise<string | null> |
Resolves to the stored value or null if not found |
| getAllKeys() | Retrieves all keys currently stored | Promise<string[]> |
Useful for iterating over all stored data |
Example: Retrieving a Value
import AsyncStorage from '@react-native-async-storage/async-storage';
const value = await AsyncStorage.getItem('userToken');
console.log(value); // Outputs the stored value or null
Example: Retrieving All Keys
import AsyncStorage from '@react-native-async-storage/async-storage';
const keys = await AsyncStorage.getAllKeys();
console.log(keys); // Outputs array of all stored keys
Note:
getItem returns a Promise that resolves to a string or null. If the key does not exist, it will return null.
4. Removing Data
Use removeItem to delete a specific key-value pair from AsyncStorage.
Example: Removing a Key-Value Pair
import AsyncStorage from '@react-native-async-storage/async-storage';
const removeUserData = async () => {
try {
await AsyncStorage.removeItem('userData');
console.log('User data removed');
} catch (error) {
console.error('Error removing data:', error);
}
};
removeUserData();
| Method | Description | Parameters | Notes |
|---|---|---|---|
| removeItem(key) | Removes the value associated with the given key | key: string |
Returns a Promise that resolves when the item is removed |
Note: If the key does not exist,
removeItem will silently succeed and return no error.
Warning: Removing data is irreversible. Ensure that the key you are removing is not needed elsewhere.
5. Clearing All Data
Use clear() to remove all key-value pairs from AsyncStorage.
Example: Clear All Data
import AsyncStorage from '@react-native-async-storage/async-storage';
const clearAllData = async () => {
try {
await AsyncStorage.clear();
console.log('All data cleared');
} catch (error) {
console.error('Failed to clear data:', error);
}
};
clearAllData();
| Method | Description | Notes |
|---|---|---|
| clear() | Removes all key-value pairs from AsyncStorage | Async operation, returns a Promise |
Note: This method clears all data for the app, including any data stored by other parts of your application or third-party libraries.
6. Getting All Keys
| Method | Description | Return Type | Notes |
|---|---|---|---|
| getAllKeys() | Retrieves all keys stored in AsyncStorage | Promise<string[]> |
Resolves with an array of all keys as strings |
Example: Getting All Keys
import AsyncStorage from '@react-native-async-storage/async-storage';
const keys = await AsyncStorage.getAllKeys();
console.log('All keys:', keys);
Note: The
getAllKeys() method returns a promise that resolves to an array of all keys currently stored in AsyncStorage. This can be useful for debugging or managing the storage state.
7. Storing Objects
Expo's AsyncStorage allows storing objects by serializing them to JSON strings. Objects must be stringified before storage and parsed after retrieval.
| Method | Description | Notes |
|---|---|---|
| setItem(key, value) | Stores a value for a given key | Value must be a string. Use JSON.stringify() for objects |
| getItem(key) | Retrieves a value for a given key | Returns a string. Use JSON.parse() to convert back to object |
Example: Storing and Retrieving an Object
import AsyncStorage from "@react-native-async-storage/async-storage";
const user = {
id: 1,
name: "John Doe",
preferences: {
theme: "dark",
notifications: true
}
};
// Store the object
const storeUser = async () => {
try {
const jsonValue = JSON.stringify(user);
await AsyncStorage.setItem("user", jsonValue);
console.log("User stored successfully");
} catch (e) {
console.error("Failed to store user", e);
}
};
// Retrieve the object
const getUser = async () => {
try {
const jsonValue = await AsyncStorage.getItem("user");
if (jsonValue != null) {
const parsedUser = JSON.parse(jsonValue);
console.log("Retrieved user:", parsedUser);
}
} catch (e) {
console.error("Failed to retrieve user", e);
}
};
Note:
AsyncStorage is a synchronous API in the React Native ecosystem but must be used with async/await or callbacks in Expo environments.
8. Using Batch Operations
Example: Batch Set and Get Operations
import AsyncStorage from '@react-native-async-storage/async-storage';
const batchOperations = [
['setItem', 'user:name', 'John Doe'],
['setItem', 'user:email', 'john@example.com'],
['setItem', 'theme', 'dark'],
];
const batchGetKeys = ['user:name', 'theme'];
async function performBatchOperations() {
try {
// Set multiple values
await AsyncStorage.multiSet(batchOperations);
// Get multiple values
const results = await AsyncStorage.multiGet(batchGetKeys);
console.log(results); // [['user:name', 'John Doe'], ['theme', 'dark']]
} catch (error) {
console.error('Batch operation failed:', error);
}
}
performBatchOperations();
| Method | Description | Parameters | Notes |
|---|---|---|---|
| multiSet | Sets multiple key-value pairs | Array<[key, value]> |
Batch operation for setting multiple items |
| multiGet | Gets multiple values by keys | Array<string> |
Returns array of [key, value] pairs |
| multiRemove | Removes multiple keys | Array<string> |
Batch operation for deleting multiple items |
| multiMerge | Merges values with existing ones (for objects) | Array<[key, value]> |
Useful for updating nested objects |
Note: Batch operations are more efficient than individual calls when working with multiple items.
Warning: All batch operations are asynchronous and return promises. Handle errors appropriately.
9. Merging Data
Example: Merging Data with AsyncStorage
import AsyncStorage from '@react-native-async-storage/async-storage';
// Sample data to merge
const newData = {
user: { name: 'John', age: 30 },
preferences: { theme: 'dark' }
};
// Retrieve existing data
const existingData = await AsyncStorage.getItem('userData');
const parsedExisting = existingData ? JSON.parse(existingData) : {};
// Merge new data with existing
const mergedData = { ...parsedExisting, ...newData };
// Save merged data back to storage
await AsyncStorage.setItem('userData', JSON.stringify(mergedData));
console.log('Merged data saved:', mergedData);
| Method | Description | Notes |
|---|---|---|
| mergeItem(key, value) | Merge new data with existing data for the specified key | Value must be a stringified JSON object or array |
| mergeAllKeys(keys, values) | Merge multiple keys with their respective values | Batch operation for efficiency |
Note: The
mergeItem method requires the stored value to be a valid JSON string. If it's not, you'll need to parse and re-serialize the data before merging.
Warning: Merging large datasets can lead to performance issues. Consider batching operations or using background threads for large data sets.
10. Handling Storage Errors
Example: Basic Error Handling with AsyncStorage
import AsyncStorage from '@react-native-async-storage/async-storage';
const storeData = async (key, value) => {
try {
await AsyncStorage.setItem(key, JSON.stringify(value));
console.log("Data stored successfully");
} catch (error) {
console.error("Error storing data:", error);
}
};
const getData = async (key) => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
return JSON.parse(value);
}
} catch (error) {
console.error("Error retrieving data:", error);
}
return null;
};
| Error Type | Description | Handling Strategy |
|---|---|---|
| Error | Generic storage error (e.g., permission denied, disk full) | Log error and provide fallback or retry logic |
| TypeError | Invalid data type passed to storage methods | Validate input before calling storage methods |
| QuotaExceededError | Storage limit exceeded (e.g., 6MB in Expo) | Implement data size checks or cleanup logic |
Note: AsyncStorage in Expo runs on top of React Native's AsyncStorage, which may throw errors depending on platform or device storage limits.
11. Removing Multiple Items
| Method | Parameters | Description |
|---|---|---|
| multiRemove | keys: string[] |
Removes multiple items from AsyncStorage by their keys. |
Example: Removing Multiple Items
import AsyncStorage from '@react-native-async-storage/async-storage';
const removeMultipleItems = async () => {
try {
await AsyncStorage.multiRemove(['key1', 'key2', 'key3']);
console.log('Items removed successfully');
} catch (error) {
console.error('Error removing items:', error);
}
};
removeMultipleItems();
Note: The
multiRemove method removes multiple items in a single operation, which is more efficient than calling removeItem multiple times.
12. Flushing Pending Operations
When using AsyncStorage, operations are batched and executed asynchronously. To ensure all pending operations are completed before proceeding, you can flush the queue manually.
| Method | Description | Notes |
|---|---|---|
| flushGetRequests() | Flushes all pending get requests and returns a promise that resolves when they are complete. | Useful for ensuring data consistency before proceeding with operations that depend on fetched values. |
Example: Flushing Pending Get Requests
import AsyncStorage from '@react-native-async-storage/async-storage';
// Set some data
await AsyncStorage.setItem('userToken', 'abc123');
// Get data (this is queued)
const token = AsyncStorage.getItem('userToken');
// Flush pending operations to ensure completion
await AsyncStorage.flushGetRequests();
// Now you can safely use the token value
console.log(token);