Storing Data Locally
Sometimes you need to save data on the device itself — user preferences, login tokens, cached data, or anything that should persist between app sessions. React Native doesn't have built-in local storage like browsers do, but the community provides AsyncStorage for this purpose.
AsyncStorage is a simple, unencrypted, key-value store. It's similar to localStorage in web browsers but asynchronous. It's great for small amounts of data like settings, tokens, and cached content.
Setting Up AsyncStorage
First, install AsyncStorage:
npm install @react-native-async-storage/async-storage
Then import and use it in your components:
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
function Settings() {
const [username, setUsername] = useState('');
const [savedUsername, setSavedUsername] = useState('');
// Load saved username on mount
useEffect(() => {
AsyncStorage.getItem('username').then(value => {
if (value) {
setSavedUsername(value);
setUsername(value);
}
});
}, []);
const saveUsername = async () => {
try {
await AsyncStorage.setItem('username', username);
setSavedUsername(username);
} catch (error) {
console.error('Error saving username:', error);
}
};
return (
<View style={{ padding: 20 }}>
<Text style={{ fontSize: 18, marginBottom: 10 }}>
Saved: {savedUsername || 'None'}
</Text>
<TextInput
value={username}
onChangeText={setUsername}
placeholder="Enter username"
style={{ borderWidth: 1, padding: 10, marginBottom: 10 }}
/>
<Button title="Save" onPress={saveUsername} />
</View>
);
}
export default Settings;
The basic operations are getItem to read and setItem to write. Both are asynchronous, so use async/await or promises. The data is stored as strings — if you need to store objects, convert them to JSON first.
Storing Objects
Since AsyncStorage only stores strings, you need to convert objects to JSON before saving and parse them when reading.
// Save an object
const saveUser = async (user) => {
try {
const jsonValue = JSON.stringify(user);
await AsyncStorage.setItem('user', jsonValue);
} catch (error) {
console.error('Error saving user:', error);
}
};
// Read an object
const getUser = async () => {
try {
const jsonValue = await AsyncStorage.getItem('user');
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch (error) {
console.error('Error reading user:', error);
return null;
}
};
// Usage
saveUser({ name: 'Alice', email: 'alice@example.com', age: 25 });
getUser().then(user => {
if (user) console.log('Hello,', user.name);
});
Always wrap AsyncStorage operations in try/catch blocks. Storage operations can fail due to disk space, corrupted data, or other issues. It's better to handle errors gracefully than to crash your app.
Removing and Clearing Data
AsyncStorage provides methods to remove specific items or clear all stored data.
// Remove a specific item
await AsyncStorage.removeItem('username');
// Clear all data (use with caution!)
await AsyncStorage.clear();
// Get all keys
const keys = await AsyncStorage.getAllKeys();
console.log('Stored keys:', keys);
Use removeItem when you need to delete specific data, like logging out a user. Use clear sparingly — it removes everything, which can break your app if you're storing important data. The getAllKeys method is useful for debugging or displaying stored data.