主题
数据请求与本地存储
状态边界
- 组件交互状态使用
useState或useReducer; - 少量跨层级状态使用 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-storagets
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-storets
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;未完成操作应具有幂等性,不能假设进程始终存活。
