技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • 基础入门

    • React Native 学习指南
    • 核心组件
    • 样式
  • 进阶内容

    • 导航
    • 网络请求
    • 本地存储
    • 常用 API

本地存储

AsyncStorage

安装

yarn add @react-native-async-storage/async-storage

# iOS
cd ios && pod install && cd ..

基础使用

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

// 存储数据
const storeData = async (key, value) => {
  try {
    await AsyncStorage.setItem(key, value);
    console.log('保存成功');
  } catch (error) {
    console.error('保存失败:', error);
  }
};

// 读取数据
const getData = async (key) => {
  try {
    const value = await AsyncStorage.getItem(key);
    if (value !== null) {
      return value;
    }
  } catch (error) {
    console.error('读取失败:', error);
  }
};

// 删除数据
const removeData = async (key) => {
  try {
    await AsyncStorage.removeItem(key);
    console.log('删除成功');
  } catch (error) {
    console.error('删除失败:', error);
  }
};

// 清空所有数据
const clearAll = async () => {
  try {
    await AsyncStorage.clear();
    console.log('清空成功');
  } catch (error) {
    console.error('清空失败:', error);
  }
};

存储对象

// 存储对象
const storeObject = async (key, object) => {
  try {
    const jsonValue = JSON.stringify(object);
    await AsyncStorage.setItem(key, jsonValue);
  } catch (error) {
    console.error('保存失败:', error);
  }
};

// 读取对象
const getObject = async (key) => {
  try {
    const jsonValue = await AsyncStorage.getItem(key);
    return jsonValue != null ? JSON.parse(jsonValue) : null;
  } catch (error) {
    console.error('读取失败:', error);
    return null;
  }
};

// 使用示例
const user = {
  id: 1,
  name: 'John',
  email: 'john@example.com'
};

await storeObject('user', user);
const savedUser = await getObject('user');
console.log(savedUser);

批量操作

// 批量存储
const multiSet = async () => {
  try {
    await AsyncStorage.multiSet([
      ['key1', 'value1'],
      ['key2', 'value2'],
      ['key3', 'value3']
    ]);
  } catch (error) {
    console.error('批量保存失败:', error);
  }
};

// 批量读取
const multiGet = async () => {
  try {
    const values = await AsyncStorage.multiGet(['key1', 'key2', 'key3']);
    console.log(values);
    // [['key1', 'value1'], ['key2', 'value2'], ['key3', 'value3']]
  } catch (error) {
    console.error('批量读取失败:', error);
  }
};

// 批量删除
const multiRemove = async () => {
  try {
    await AsyncStorage.multiRemove(['key1', 'key2', 'key3']);
  } catch (error) {
    console.error('批量删除失败:', error);
  }
};

// 获取所有键
const getAllKeys = async () => {
  try {
    const keys = await AsyncStorage.getAllKeys();
    console.log(keys);
  } catch (error) {
    console.error('获取键失败:', error);
  }
};

封装 Storage 工具

// utils/storage.js
import AsyncStorage from '@react-native-async-storage/async-storage';

class Storage {
  // 存储字符串
  static async set(key, value) {
    try {
      await AsyncStorage.setItem(key, value);
      return true;
    } catch (error) {
      console.error('Storage set error:', error);
      return false;
    }
  }

  // 读取字符串
  static async get(key, defaultValue = null) {
    try {
      const value = await AsyncStorage.getItem(key);
      return value !== null ? value : defaultValue;
    } catch (error) {
      console.error('Storage get error:', error);
      return defaultValue;
    }
  }

  // 存储对象
  static async setObject(key, object) {
    try {
      const jsonValue = JSON.stringify(object);
      await AsyncStorage.setItem(key, jsonValue);
      return true;
    } catch (error) {
      console.error('Storage setObject error:', error);
      return false;
    }
  }

  // 读取对象
  static async getObject(key, defaultValue = null) {
    try {
      const jsonValue = await AsyncStorage.getItem(key);
      return jsonValue != null ? JSON.parse(jsonValue) : defaultValue;
    } catch (error) {
      console.error('Storage getObject error:', error);
      return defaultValue;
    }
  }

  // 删除
  static async remove(key) {
    try {
      await AsyncStorage.removeItem(key);
      return true;
    } catch (error) {
      console.error('Storage remove error:', error);
      return false;
    }
  }

  // 清空
  static async clear() {
    try {
      await AsyncStorage.clear();
      return true;
    } catch (error) {
      console.error('Storage clear error:', error);
      return false;
    }
  }

  // 获取所有键
  static async getAllKeys() {
    try {
      return await AsyncStorage.getAllKeys();
    } catch (error) {
      console.error('Storage getAllKeys error:', error);
      return [];
    }
  }

  // 合并对象
  static async mergeObject(key, object) {
    try {
      const jsonValue = JSON.stringify(object);
      await AsyncStorage.mergeItem(key, jsonValue);
      return true;
    } catch (error) {
      console.error('Storage mergeObject error:', error);
      return false;
    }
  }
}

export default Storage;

使用封装的 Storage

import Storage from './utils/storage';

// 存储用户信息
await Storage.setObject('user', {
  id: 1,
  name: 'John',
  email: 'john@example.com'
});

// 读取用户信息
const user = await Storage.getObject('user');

// 存储 token
await Storage.set('token', 'your-token-here');

// 读取 token
const token = await Storage.get('token');

// 删除 token
await Storage.remove('token');

// 清空所有数据
await Storage.clear();

实战:用户认证状态管理

// contexts/AuthContext.js
import React, { createContext, useState, useEffect, useContext } from 'react';
import Storage from '../utils/storage';

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [token, setToken] = useState(null);
  const [loading, setLoading] = useState(true);

  // 初始化:从本地存储读取用户信息
  useEffect(() => {
    loadUserFromStorage();
  }, []);

  const loadUserFromStorage = async () => {
    try {
      const savedUser = await Storage.getObject('user');
      const savedToken = await Storage.get('token');
      
      if (savedUser && savedToken) {
        setUser(savedUser);
        setToken(savedToken);
      }
    } catch (error) {
      console.error('加载用户信息失败:', error);
    } finally {
      setLoading(false);
    }
  };

  // 登录
  const login = async (userData, authToken) => {
    try {
      await Storage.setObject('user', userData);
      await Storage.set('token', authToken);
      setUser(userData);
      setToken(authToken);
      return true;
    } catch (error) {
      console.error('登录失败:', error);
      return false;
    }
  };

  // 登出
  const logout = async () => {
    try {
      await Storage.remove('user');
      await Storage.remove('token');
      setUser(null);
      setToken(null);
      return true;
    } catch (error) {
      console.error('登出失败:', error);
      return false;
    }
  };

  // 更新用户信息
  const updateUser = async (updates) => {
    try {
      const updatedUser = { ...user, ...updates };
      await Storage.setObject('user', updatedUser);
      setUser(updatedUser);
      return true;
    } catch (error) {
      console.error('更新用户信息失败:', error);
      return false;
    }
  };

  const value = {
    user,
    token,
    loading,
    isAuthenticated: !!user && !!token,
    login,
    logout,
    updateUser
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within AuthProvider');
  }
  return context;
}

使用 AuthContext

// App.js
import { AuthProvider } from './contexts/AuthContext';

function App() {
  return (
    <AuthProvider>
      <Navigation />
    </AuthProvider>
  );
}

// screens/LoginScreen.js
import { useAuth } from '../contexts/AuthContext';

function LoginScreen({ navigation }) {
  const { login } = useAuth();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleLogin = async () => {
    try {
      const response = await fetch('https://api.example.com/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password })
      });

      const data = await response.json();
      
      if (data.success) {
        await login(data.user, data.token);
        navigation.replace('Home');
      }
    } catch (error) {
      Alert.alert('错误', '登录失败');
    }
  };

  return (
    <View>
      <TextInput
        placeholder="邮箱"
        value={email}
        onChangeText={setEmail}
      />
      <TextInput
        placeholder="密码"
        value={password}
        onChangeText={setPassword}
        secureTextEntry
      />
      <Button title="登录" onPress={handleLogin} />
    </View>
  );
}

// screens/ProfileScreen.js
function ProfileScreen() {
  const { user, logout } = useAuth();

  const handleLogout = async () => {
    await logout();
    navigation.replace('Login');
  };

  return (
    <View>
      <Text>姓名: {user?.name}</Text>
      <Text>邮箱: {user?.email}</Text>
      <Button title="退出登录" onPress={handleLogout} />
    </View>
  );
}

实战:应用设置管理

// contexts/SettingsContext.js
import React, { createContext, useState, useEffect, useContext } from 'react';
import Storage from '../utils/storage';

const SettingsContext = createContext();

const DEFAULT_SETTINGS = {
  theme: 'light', // light | dark
  language: 'zh-CN', // zh-CN | en-US
  notifications: true,
  fontSize: 'medium' // small | medium | large
};

export function SettingsProvider({ children }) {
  const [settings, setSettings] = useState(DEFAULT_SETTINGS);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    loadSettings();
  }, []);

  const loadSettings = async () => {
    try {
      const savedSettings = await Storage.getObject('settings', DEFAULT_SETTINGS);
      setSettings(savedSettings);
    } catch (error) {
      console.error('加载设置失败:', error);
    } finally {
      setLoading(false);
    }
  };

  const updateSettings = async (updates) => {
    try {
      const newSettings = { ...settings, ...updates };
      await Storage.setObject('settings', newSettings);
      setSettings(newSettings);
      return true;
    } catch (error) {
      console.error('更新设置失败:', error);
      return false;
    }
  };

  const resetSettings = async () => {
    try {
      await Storage.setObject('settings', DEFAULT_SETTINGS);
      setSettings(DEFAULT_SETTINGS);
      return true;
    } catch (error) {
      console.error('重置设置失败:', error);
      return false;
    }
  };

  const value = {
    settings,
    loading,
    updateSettings,
    resetSettings
  };

  return (
    <SettingsContext.Provider value={value}>
      {children}
    </SettingsContext.Provider>
  );
}

export function useSettings() {
  const context = useContext(SettingsContext);
  if (!context) {
    throw new Error('useSettings must be used within SettingsProvider');
  }
  return context;
}

使用 SettingsContext

// screens/SettingsScreen.js
import { useSettings } from '../contexts/SettingsContext';

function SettingsScreen() {
  const { settings, updateSettings, resetSettings } = useSettings();

  return (
    <ScrollView style={{ flex: 1, padding: 20 }}>
      <Text style={{ fontSize: 24, fontWeight: 'bold', marginBottom: 20 }}>
        设置
      </Text>

      {/* 主题设置 */}
      <View style={{ marginBottom: 20 }}>
        <Text style={{ fontSize: 16, marginBottom: 10 }}>主题</Text>
        <View style={{ flexDirection: 'row' }}>
          <TouchableOpacity
            style={{
              padding: 10,
              backgroundColor: settings.theme === 'light' ? '#007AFF' : '#eee',
              borderRadius: 5,
              marginRight: 10
            }}
            onPress={() => updateSettings({ theme: 'light' })}
          >
            <Text style={{ color: settings.theme === 'light' ? '#fff' : '#333' }}>
              浅色
            </Text>
          </TouchableOpacity>
          
          <TouchableOpacity
            style={{
              padding: 10,
              backgroundColor: settings.theme === 'dark' ? '#007AFF' : '#eee',
              borderRadius: 5
            }}
            onPress={() => updateSettings({ theme: 'dark' })}
          >
            <Text style={{ color: settings.theme === 'dark' ? '#fff' : '#333' }}>
              深色
            </Text>
          </TouchableOpacity>
        </View>
      </View>

      {/* 通知设置 */}
      <View style={{ marginBottom: 20 }}>
        <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
          <Text style={{ fontSize: 16 }}>推送通知</Text>
          <Switch
            value={settings.notifications}
            onValueChange={(value) => updateSettings({ notifications: value })}
          />
        </View>
      </View>

      {/* 重置按钮 */}
      <TouchableOpacity
        style={{
          backgroundColor: '#FF3B30',
          padding: 15,
          borderRadius: 8,
          marginTop: 20
        }}
        onPress={() => {
          Alert.alert(
            '确认',
            '确定要重置所有设置吗?',
            [
              { text: '取消', style: 'cancel' },
              { text: '确定', onPress: resetSettings }
            ]
          );
        }}
      >
        <Text style={{ color: '#fff', textAlign: 'center', fontWeight: 'bold' }}>
          重置设置
        </Text>
      </TouchableOpacity>
    </ScrollView>
  );
}

注意事项

  1. 数据大小限制:AsyncStorage 适合存储小量数据(< 6MB)
  2. 异步操作:所有操作都是异步的,记得使用 async/await
  3. 数据类型:只能存储字符串,对象需要 JSON 序列化
  4. 错误处理:始终使用 try-catch 处理可能的错误
  5. 性能考虑:避免频繁读写,可以使用内存缓存
  6. 安全性:敏感数据应该加密存储
最近更新: 2026/2/6 15:39
Contributors: hailong
Prev
网络请求
Next
常用 API