Skip to content

数据请求与本地存储

状态边界

  • 组件交互状态使用 useStateuseReducer
  • 少量跨层级状态使用 Context;
  • 服务端数据应处理加载、错误、取消、缓存与重新验证;
  • 持久化存储只保存恢复应用所需的数据,不作为内存状态的直接替代。

网络请求

React Native 提供标准 fetch API。网络失败与 HTTP 错误需要分别处理:

tsx
import { useEffect, useState } from 'react'

type User = { id: string; name: string }

export function useUser(id: string) {
  const [user, setUser] = useState<User | null>(null)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    const controller = new AbortController()

    async function load() {
      try {
        const response = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/users/${id}`, {
          signal: controller.signal,
        })

        if (!response.ok) throw new Error(`HTTP ${response.status}`)
        setUser((await response.json()) as User)
      } catch (value) {
        if (!controller.signal.aborted) {
          setError(value instanceof Error ? value : new Error('请求失败'))
        }
      }
    }

    void load()
    return () => controller.abort()
  }, [id])

  return { user, error }
}

真机中的 localhost 指向手机自身。访问电脑上的本地服务时,应使用局域网地址,或使用模拟器对应的宿主机网络地址。

AsyncStorage

AsyncStorage 适合保存偏好、草稿和非敏感缓存。值以字符串形式存储:

bash
npx expo install @react-native-async-storage/async-storage
ts
import AsyncStorage from '@react-native-async-storage/async-storage'

type Preferences = { theme: 'light' | 'dark' }

export async function savePreferences(value: Preferences) {
  await AsyncStorage.setItem('preferences', JSON.stringify(value))
}

export async function readPreferences(): Promise<Preferences | null> {
  const value = await AsyncStorage.getItem('preferences')
  return value ? (JSON.parse(value) as Preferences) : null
}

解析持久化数据时应校验结构,并为旧版本数据提供迁移或默认值。

SecureStore

访问令牌等小型敏感值使用系统安全存储:

bash
npx expo install expo-secure-store
ts
import * as SecureStore from 'expo-secure-store'

export async function saveAccessToken(token: string) {
  await SecureStore.setItemAsync('access-token', token)
}

export async function readAccessToken() {
  return SecureStore.getItemAsync('access-token')
}

SecureStore 不适合存放大量数据,也不能替代服务端会话失效与令牌轮换机制。

应用生命周期

移动应用可能进入后台、被系统挂起或终止。需要在恢复前台时刷新的数据,可监听 AppState;未完成操作应具有幂等性,不能假设进程始终存活。

参考资料

基于 MIT 许可发布