React Native AsyncStorage #
概述 #
AsyncStorage 是 React Native 的异步、持久化键值存储系统。它用于存储小型数据,如用户偏好、令牌、缓存等。
安装 #
bash
npm install @react-native-async-storage/async-storage
iOS 需要 pod install:
bash
cd ios && pod install
基本操作 #
存储数据 #
tsx
import AsyncStorage from '@react-native-async-storage/async-storage';
const storeData = async (key: string, value: string) => {
try {
await AsyncStorage.setItem(key, value);
console.log('Data saved successfully');
} catch (error) {
console.error('Error saving data:', error);
}
};
// 使用示例
await storeData('username', 'john_doe');
读取数据 #
tsx
const getData = async (key: string): Promise<string | null> => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
return value;
}
return null;
} catch (error) {
console.error('Error reading data:', error);
return null;
}
};
// 使用示例
const username = await getData('username');
console.log('Username:', username);
删除数据 #
tsx
const removeData = async (key: string) => {
try {
await AsyncStorage.removeItem(key);
console.log('Data removed successfully');
} catch (error) {
console.error('Error removing data:', error);
}
};
// 使用示例
await removeData('username');
清空所有数据 #
tsx
const clearAll = async () => {
try {
await AsyncStorage.clear();
console.log('All data cleared');
} catch (error) {
console.error('Error clearing data:', error);
}
};
存储对象 #
AsyncStorage 只能存储字符串,需要使用 JSON 序列化。
存储对象 #
tsx
interface User {
id: string;
name: string;
email: string;
}
const storeUser = async (user: User) => {
try {
const jsonValue = JSON.stringify(user);
await AsyncStorage.setItem('user', jsonValue);
} catch (error) {
console.error('Error storing user:', error);
}
};
读取对象 #
tsx
const getUser = async (): Promise<User | null> => {
try {
const jsonValue = await AsyncStorage.getItem('user');
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch (error) {
console.error('Error getting user:', error);
return null;
}
};
存储数组 #
tsx
interface Todo {
id: string;
text: string;
completed: boolean;
}
const storeTodos = async (todos: Todo[]) => {
try {
await AsyncStorage.setItem('todos', JSON.stringify(todos));
} catch (error) {
console.error('Error storing todos:', error);
}
};
const getTodos = async (): Promise<Todo[]> => {
try {
const jsonValue = await AsyncStorage.getItem('todos');
return jsonValue ? JSON.parse(jsonValue) : [];
} catch (error) {
console.error('Error getting todos:', error);
return [];
}
};
批量操作 #
批量存储 #
tsx
const storeMultiple = async (data: Record<string, string>) => {
try {
const pairs: [string, string][] = Object.entries(data);
await AsyncStorage.multiSet(pairs);
console.log('Multiple items stored');
} catch (error) {
console.error('Error storing multiple items:', error);
}
};
// 使用示例
await storeMultiple({
username: 'john_doe',
email: 'john@example.com',
theme: 'dark',
});
批量读取 #
tsx
const getMultiple = async (keys: string[]): Promise<Record<string, string | null>> => {
try {
const pairs = await AsyncStorage.multiGet(keys);
const result: Record<string, string | null> = {};
pairs.forEach(([key, value]) => {
result[key] = value;
});
return result;
} catch (error) {
console.error('Error getting multiple items:', error);
return {};
}
};
// 使用示例
const data = await getMultiple(['username', 'email', 'theme']);
console.log(data);
批量删除 #
tsx
const removeMultiple = async (keys: string[]) => {
try {
await AsyncStorage.multiRemove(keys);
console.log('Multiple items removed');
} catch (error) {
console.error('Error removing multiple items:', error);
}
};
获取所有键 #
tsx
const getAllKeys = async (): Promise<string[]> => {
try {
const keys = await AsyncStorage.getAllKeys();
return keys;
} catch (error) {
console.error('Error getting all keys:', error);
return [];
}
};
封装存储服务 #
创建一个可复用的存储服务:
tsx
import AsyncStorage from '@react-native-async-storage/async-storage';
class StorageService {
private static instance: StorageService;
private constructor() {}
static getInstance(): StorageService {
if (!StorageService.instance) {
StorageService.instance = new StorageService();
}
return StorageService.instance;
}
async set<T>(key: string, value: T): Promise<void> {
try {
const jsonValue = JSON.stringify(value);
await AsyncStorage.setItem(key, jsonValue);
} catch (error) {
console.error(`Error saving ${key}:`, error);
throw error;
}
}
async get<T>(key: string): Promise<T | null> {
try {
const jsonValue = await AsyncStorage.getItem(key);
return jsonValue ? JSON.parse(jsonValue) : null;
} catch (error) {
console.error(`Error reading ${key}:`, error);
return null;
}
}
async remove(key: string): Promise<void> {
try {
await AsyncStorage.removeItem(key);
} catch (error) {
console.error(`Error removing ${key}:`, error);
throw error;
}
}
async clear(): Promise<void> {
try {
await AsyncStorage.clear();
} catch (error) {
console.error('Error clearing storage:', error);
throw error;
}
}
async getAllKeys(): Promise<string[]> {
try {
return await AsyncStorage.getAllKeys();
} catch (error) {
console.error('Error getting all keys:', error);
return [];
}
}
}
export default StorageService.getInstance();
使用封装服务 #
tsx
import storage from './StorageService';
const saveUser = async (user: User) => {
await storage.set('user', user);
};
const loadUser = async (): Promise<User | null> => {
return await storage.get<User>('user');
};
使用 Hook #
创建自定义 Hook 简化使用:
tsx
import {useState, useEffect} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
function useStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(initialValue);
const [loading, setLoading] = useState(true);
useEffect(() => {
const loadValue = async () => {
try {
const jsonValue = await AsyncStorage.getItem(key);
if (jsonValue !== null) {
setStoredValue(JSON.parse(jsonValue));
}
} catch (error) {
console.error(`Error loading ${key}:`, error);
} finally {
setLoading(false);
}
};
loadValue();
}, [key]);
const setValue = async (value: T) => {
try {
setStoredValue(value);
await AsyncStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(`Error saving ${key}:`, error);
}
};
const removeValue = async () => {
try {
setStoredValue(initialValue);
await AsyncStorage.removeItem(key);
} catch (error) {
console.error(`Error removing ${key}:`, error);
}
};
return {value: storedValue, setValue, removeValue, loading};
}
export default useStorage;
使用 Hook #
tsx
import React from 'react';
import {View, Text, Button, TextInput, StyleSheet} from 'react-native';
import useStorage from './useStorage';
const SettingsScreen = () => {
const {value: theme, setValue: setTheme, loading} = useStorage('theme', 'light');
const {value: username, setValue: setUsername} = useStorage('username', '');
if (loading) {
return <Text>Loading...</Text>;
}
return (
<View style={styles.container}>
<Text>Theme: {theme}</Text>
<Button
title="Toggle Theme"
onPress={() => setTheme(theme === 'light' ? 'dark' : 'light')}
/>
<TextInput
value={username}
onChangeText={setUsername}
placeholder="Username"
style={styles.input}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
input: {
height: 48,
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8,
paddingHorizontal: 16,
marginTop: 16,
},
});
export default SettingsScreen;
加密存储 #
对于敏感数据,需要加密存储:
bash
npm install react-native-keychain
tsx
import * as Keychain from 'react-native-keychain';
const saveSecureValue = async (key: string, value: string) => {
try {
await Keychain.setGenericPassword(key, value, {
service: key,
});
} catch (error) {
console.error('Error saving secure value:', error);
}
};
const getSecureValue = async (key: string): Promise<string | null> => {
try {
const result = await Keychain.getGenericPassword({service: key});
return result ? result.password : null;
} catch (error) {
console.error('Error getting secure value:', error);
return null;
}
};
const removeSecureValue = async (key: string) => {
try {
await Keychain.resetGenericPassword({service: key});
} catch (error) {
console.error('Error removing secure value:', error);
}
};
缓存管理 #
带过期时间的缓存 #
tsx
interface CacheItem<T> {
data: T;
timestamp: number;
expiresIn: number;
}
const setCache = async <T>(key: string, data: T, expiresIn: number) => {
const item: CacheItem<T> = {
data,
timestamp: Date.now(),
expiresIn,
};
await AsyncStorage.setItem(key, JSON.stringify(item));
};
const getCache = async <T>(key: string): Promise<T | null> => {
try {
const jsonValue = await AsyncStorage.getItem(key);
if (!jsonValue) return null;
const item: CacheItem<T> = JSON.parse(jsonValue);
const now = Date.now();
if (now - item.timestamp > item.expiresIn) {
await AsyncStorage.removeItem(key);
return null;
}
return item.data;
} catch (error) {
return null;
}
};
// 使用示例:缓存 API 响应 5 分钟
const fetchUserWithCache = async (userId: string) => {
const cacheKey = `user_${userId}`;
const cached = await getCache<User>(cacheKey);
if (cached) {
return cached;
}
const user = await fetchUser(userId);
await setCache(cacheKey, user, 5 * 60 * 1000);
return user;
};
最佳实践 #
键命名规范 #
tsx
const STORAGE_KEYS = {
USER: '@app:user',
TOKEN: '@app:token',
THEME: '@app:theme',
CART: '@app:cart',
NOTIFICATIONS: '@app:notifications',
} as const;
// 使用
await AsyncStorage.setItem(STORAGE_KEYS.USER, jsonValue);
错误处理 #
tsx
const safeStorage = {
async get<T>(key: string): Promise<T | null> {
try {
const value = await AsyncStorage.getItem(key);
return value ? JSON.parse(value) : null;
} catch (error) {
console.error(`Storage get error for ${key}:`, error);
return null;
}
},
async set<T>(key: string, value: T): Promise<boolean> {
try {
await AsyncStorage.setItem(key, JSON.stringify(value));
return true;
} catch (error) {
console.error(`Storage set error for ${key}:`, error);
return false;
}
},
};
数据迁移 #
tsx
const migrateData = async () => {
const version = await AsyncStorage.getItem('@app:version');
if (!version) {
// 首次安装,初始化数据
await AsyncStorage.setItem('@app:version', '1.0.0');
} else if (version === '1.0.0') {
// 从 1.0.0 迁移到 1.1.0
const oldData = await AsyncStorage.getItem('old_key');
if (oldData) {
await AsyncStorage.setItem('new_key', oldData);
await AsyncStorage.removeItem('old_key');
}
await AsyncStorage.setItem('@app:version', '1.1.0');
}
};
限制 #
- 大小限制:Android 默认 6MB,iOS 无限制但建议不超过 2MB
- 性能:大量数据时性能下降,建议使用数据库
- 同步:所有操作都是异步的
总结 #
AsyncStorage 是 React Native 的基础存储方案:
- 适合存储小型数据
- 支持字符串、对象、数组
- 提供批量操作
- 敏感数据使用 Keychain
对于大量数据或复杂查询,建议使用 SQLite 或 Realm。
继续学习 网络请求,了解 API 调用和数据处理。
最后更新:2026-03-28