普通视图

发现新文章,点击刷新页面。
昨天 — 2026年4月13日首页

如何实现RN应用的离线功能、数据缓存策略?

作者 光影少年
2026年4月12日 20:29

React Native(RN) 里实现“离线可用 + 数据缓存”,本质是两件事:

① 本地持久化数据(缓存)
② 网络恢复后的同步策略(离线→在线)

我给你按“能直接落地”的思路讲,不整虚的👇


🧩 一、离线能力的整体架构

一个靠谱的 RN 离线方案一般是这样:

接口请求 → 缓存层 → UI展示
            ↓
        本地存储(数据库/缓存)
            ↓
        同步机制(网络恢复)

核心点就3个:

  1. 缓存数据
  2. 判断网络状态
  3. 同步数据(冲突处理)

📦 二、本地存储方案选型(很关键)

1️⃣ 轻量缓存(推荐入门)

👉 AsyncStorage

适合:

  • token
  • 用户信息
  • 小量接口缓存
import AsyncStorage from '@react-native-async-storage/async-storage'

// 存
await AsyncStorage.setItem('user', JSON.stringify(user))

// 取
const user = JSON.parse(await AsyncStorage.getItem('user'))

👉 ❗缺点:

  • 不适合大数据
  • 没查询能力

2️⃣ 高性能KV缓存(推荐)

👉 react-native-mmkv

优势:

  • C++实现,性能非常高
  • 支持同步读取(比 AsyncStorage 快很多)
import { MMKV } from 'react-native-mmkv'

const storage = new MMKV()

storage.set('name', 'zhang')
const name = storage.getString('name')

👉 适合:

  • 高频读写
  • 状态缓存(Redux持久化)

3️⃣ 本地数据库(复杂业务必选)

👉 realm

  • 离线能力强
  • 支持对象存储
  • 自动同步(可选)

👉 SQLite

  • 更底层
  • 灵活但要自己写SQL

👉 适合:

  • 列表数据
  • 离线表单
  • 聊天记录

🌐 三、网络状态监听(离线核心)

👉 用:@react-native-community/netinfo

import NetInfo from "@react-native-community/netinfo";

NetInfo.addEventListener(state => {
  console.log("是否联网:", state.isConnected);
});

👉 用途:

  • 判断是否走缓存
  • 触发“数据同步”

🔁 四、数据缓存策略(重点)

🧠 策略1:Cache First(优先缓存)

👉 打开页面先读缓存,再请求接口更新

const cache = await getCache()

if (cache) {
  setData(cache)
}

fetchApi().then(res => {
  setData(res)
  saveCache(res)
})

👉 优点:

  • 秒开
  • 离线可用

🧠 策略2:Network First(优先网络)

try {
  const res = await fetchApi()
  saveCache(res)
  return res
} catch {
  return getCache()
}

👉 优点:

  • 数据新
    👉 缺点:
  • 离线体验一般

🧠 策略3:Stale-While-Revalidate(推荐)

👉 最适合RN

先用缓存  后台更新  UI刷新

👉 类似 Web 的 SWR


📝 五、离线写入(重点难点🔥)

比如:

👉 用户离线提交表单 / 点赞 / 操作

你要做:

1️⃣ 本地先存操作(队列)

const queue = [
  { type: 'CREATE', data: {...}, status: 'pending' }
]

2️⃣ 网络恢复后同步

if (isOnline) {
  queue.forEach(async item => {
    await api(item)
    markDone(item)
  })
}

3️⃣ 冲突处理(很关键)

常见策略:

  • 时间戳优先(last-write-wins)
  • 版本号控制
  • 服务端合并

⚡ 六、工程级方案(推荐你用)

👉 状态管理 + 持久化

  • Redux + redux-persist
  • Zustand + persist

👉 Zustand示例:

import { create } from 'zustand'
import { persist } from 'zustand/middleware'

const useStore = create(persist(
  (set) => ({
    user: null,
    setUser: (user) => set({ user })
  }),
  { name: 'app-storage' }
))

👉 请求缓存库(高级)

  • react-query(TanStack Query)
  • SWR(也有RN版本)

👉 react-query支持:

  • 自动缓存
  • 重试
  • 离线恢复

🚀 七、一个完整落地方案(推荐你这样做)

结合你现在前端背景,我给你一个“企业级方案”👇

RN App
├── Zustand(状态管理)
├── MMKV(本地缓存)
├── React Query(接口缓存)
├── NetInfo(网络检测)
└── Sync Queue(离线同步)

🧠 总结(最重要)

👉 RN离线能力 =

缓存(读) + 队列(写) + 同步(网络恢复)

🎯 给你的进阶建议(很关键)

你现在是前端出身,可以重点搞这个方向:

👉 “离线优先应用(Offline-first App)”

做一个项目练手:

  • 离线Todo App(带同步)
  • 离线表单系统(类似工单)
  • IoT设备数据缓存(结合你Go也能玩)
昨天以前首页

RN中如何处理权限申请(相机、相册、定位、存储)?使用第三方库还是原生封装?

作者 光影少年
2026年4月11日 12:02

在 React Native(RN)里处理权限申请,本质上有两条路:

一、推荐方案:使用第三方库(更省心 ✅)

最主流的是 👉 react-native-permissions

为什么推荐它?

  • 一套 API 统一处理 iOS + Android
  • 覆盖:相机 / 相册 / 定位 / 麦克风 / 通讯录等
  • 自动处理不同系统版本差异(特别是 Android 10+、13+)

安装

yarn add react-native-permissions

iOS 还需要:

cd ios && pod install

基本用法(以相机为例)

import {request, PERMISSIONS, RESULTS} from 'react-native-permissions';
import {Platform} from 'react-native';

export async function requestCameraPermission() {
  const permission =
    Platform.OS === 'ios'
      ? PERMISSIONS.IOS.CAMERA
      : PERMISSIONS.ANDROID.CAMERA;

  const result = await request(permission);

  switch (result) {
    case RESULTS.GRANTED:
      console.log('已授权');
      break;
    case RESULTS.DENIED:
      console.log('用户拒绝');
      break;
    case RESULTS.BLOCKED:
      console.log('被永久拒绝,需要引导去设置页');
      break;
  }
}

常见权限对应表

功能 iOS Android
相机 CAMERA CAMERA
相册 PHOTO_LIBRARY READ_MEDIA_IMAGES(Android 13+)
定位 LOCATION_WHEN_IN_USE ACCESS_FINE_LOCATION
存储 自动 READ/WRITE_EXTERNAL_STORAGE(已逐步废弃)

跳转系统设置页(很重要)

import {openSettings} from 'react-native-permissions';

openSettings();

二、官方原生 API(不推荐做主方案 ❌)

RN 自带:

👉 PermissionsAndroid(仅 Android)

import {PermissionsAndroid} from 'react-native';

await PermissionsAndroid.request(
  PermissionsAndroid.PERMISSIONS.CAMERA
);

问题:

  • ❌ iOS 不支持(需要自己写 Native)
  • ❌ Android 版本适配麻烦(13+权限拆分)
  • ❌ 代码分散,难维护

三、什么时候用“原生封装”?🤔

只有这些情况才建议:

✅ 场景

  • 需要深度定制(比如蓝牙、后台定位)
  • 使用原生 SDK(高德 / 百度定位)
  • 公司有统一权限中间层

❌ 不建议

  • 普通业务(拍照、选图、定位)
  • 中小项目

四、最佳实践(很关键🔥)

1️⃣ 封装统一权限工具

// permission.ts
export async function requestPermission(type: 'camera' | 'photo' | 'location') {
  // 内部统一处理
}

👉 避免业务代码到处写权限逻辑


2️⃣ 权限申请时机

不要一进 App 就申请 ❌
👉 要“用到时再申请” ✅

例如:

  • 点击“拍照” → 再申请相机权限
  • 点击“上传头像” → 再申请相册

3️⃣ 权限被拒绝的处理

if (result === RESULTS.BLOCKED) {
  Alert.alert(
    '需要权限',
    '请前往设置开启权限',
    [
      {text: '取消'},
      {text: '去设置', onPress: openSettings}
    ]
  );
}

4️⃣ Android 13+ 注意点 ⚠️

存储权限拆分为:

  • READ_MEDIA_IMAGES
  • READ_MEDIA_VIDEO
  • READ_MEDIA_AUDIO

👉 用旧的 READ_EXTERNAL_STORAGE 会失效


五、总结(给你一个明确建议)

👉 90% 场景建议:

  • 用 👉 react-native-permissions
❌
❌