- Published on
React Native 数据持久化
在移动应用开发中,数据持久化 (Data Persistence) 是一项基本需求,它使得应用能够在关闭和重启后,依然能恢复用户的设置、会话信息或其他关键数据。React Native 作为一个跨平台框架,提供了多种实现本地数据存储的方案。其中,AsyncStorage 是社区中最广为人知、最基础的解决方案。
AsyncStorage 核心机制与历史演进
定义与实现
syncStorage 是一个简单的、未加密的、异步的、持久化的键值 (key-value) 存储系统,它在应用级别上对数据进行全局存储。
历史演进
AsyncStorage 最初是 React Native 核心库的一部分。为了使核心库更加精简,它后来被剥离出来,现在由社区进行维护。在新的项目中,需要通过以下方式单独安装:
npm install @react-native-async-storage/async-storage
与 localStorage 的关键区别:异步 vs. 同步
AsyncStorage 在概念上最接近 Web 开发中的 Window.localStorage,但它们之间存在一个根本性的差异:
localStorage(Web): 是一个同步 (synchronous) 的 API。当你调用localStorage.setItem()时,它会阻塞主线程,直到数据写入磁盘完成。对于小数据,这种阻塞微不足道,但对于大数据或频繁操作,则可能导致 UI 卡顿。AsyncStorage(React Native): 是一个完全异步 (asynchronous) 的 API。所有的数据操作(读/写/删除)都会返回一个Promise对象。这种设计确保了磁盘 I/O 操作不会阻塞 JavaScript 主线程,从而保证了应用 UI 的流畅响应。
AsyncStorage 的核心 API 实践
存储与读取数据
由于 API 是异步的,最佳实践是结合 async/await 语法来使用。
数据类型限制
AsyncStorage 只能存储字符串数据。如果要存储对象或数组等复杂数据类型,必须在存入前通过 JSON.stringify() 将其序列化为字符串,在读取后通过 JSON.parse() 将其反序列化。
import AsyncStorage from '@react-native-async-storage/async-storage';
import React from 'react';
import { View, Button } from 'react-native';
const USER_SETTINGS_KEY = '@user_settings';
const App = () => {
const saveSettings = async () => {
try {
const settings = {
theme: 'dark',
notifications: true,
};
// 1. 将对象序列化为字符串
const jsonValue = JSON.stringify(settings);
// 2. 异步存储
await AsyncStorage.setItem(USER_SETTINGS_KEY, jsonValue);
console.log('Settings saved successfully.');
} catch (e) {
console.error('Failed to save settings.', e);
}
};
const loadSettings = async () => {
try {
// 3. 异步读取
const jsonValue = await AsyncStorage.getItem(USER_SETTINGS_KEY);
// 4. 如果值存在,则反序列化
const settings = jsonValue != null ? JSON.parse(jsonValue) : null;
if (settings !== null) {
console.log('Loaded settings:', settings);
}
} catch (e) {
console.error('Failed to load settings.', e);
}
};
return (
<View>
<Button title="Save Settings" onPress={saveSettings} />
<Button title="Load Settings" onPress={loadSettings} />
</View>
);
};
其他常用方法
removeItem(key): 异步删除一个键值对。clear(): 异步清空所有存储的数据。getAllKeys(): 异步获取所有已存储的键名。multiGet(keys)/multiSet(keyValuePairs): 用于一次性、批量地读取或写入多个键值对。
局限性与替代方案
AsyncStorage 虽然简单易用,但也存在一些局限性,使其不适用于所有场景。
安全性警告
AsyncStorage 是未加密的。数据以明文形式存储在设备上,任何能够访问设备文件系统的人(例如在越狱/root 过的设备上)都可能读取到这些数据。绝对不要用它来存储密码、私钥、API Tokens 等高度敏感的信息。
- 性能局限: 对于大量或频繁的数据读写,
AsyncStorage的性能可能会成为瓶颈,因为它在底层可能依赖于序列化到一个大的 JSON 文件或多个小文件。 - 替代方案:
- MMKV: 一个由腾讯开发的高性能、持久化的键值存储框架。它通过内存映射 (memory mapping) 技术实现了极高的数据读写速度,并且其 API 是同步的(但由于其 C++ 底层实现极快,通常不会阻塞 UI)。
- SQLite: 对于需要存储大量结构化、关系型数据的场景,应使用更专业的数据库解决方案。
react-native-sqlite-storage是一个常用的社区库。 - 安全存储: 对于需要加密存储的敏感凭据(如 API Token、密码),应使用专门的安全存储库,如
react-native-keychain,它利用了 iOS 的 Keychain 和 Android 的 Keystore 等平台级的安全特性。