You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在集成Redux、redux-persist、redux-thunk的React Native项目中使用react-native-offline

基于Redux、redux-persist和redux-thunk实现React Native离线支持

1. 配置Store(整合redux-persist与react-native-offline)

先调整Store创建逻辑,加入react-native-offline核心中间件,同时确保离线请求队列能被redux-persist持久化:

import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { createNetworkMiddleware, offlineMiddleware } from 'react-native-offline';

// 导入你的业务reducer
import appReducer from './appReducer';
// 离线队列reducer(后续定义)
import offlineQueueReducer from './offlineQueueReducer';

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  whitelist: ['offlineQueue'], // 仅持久化队列状态
};

// 网络状态检测中间件,控制队列执行节流
const networkMiddleware = createNetworkMiddleware({
  queueReleaseThrottle: 200,
});

const rootReducer = combineReducers({
  app: appReducer,
  offlineQueue: offlineQueueReducer,
});

const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = createStore(
  persistedReducer,
  applyMiddleware(
    thunk,
    networkMiddleware,
    offlineMiddleware
  )
);

export const persistor = persistStore(store);

2. 定义离线队列的Action与Reducer

创建专门管理离线请求的状态模块:

Action 定义

// src/actions/offlineActions.js
export const ADD_TO_QUEUE = 'ADD_TO_QUEUE';
export const CLEAR_QUEUE = 'CLEAR_QUEUE';

export const addToOfflineQueue = (request) => ({
  type: ADD_TO_QUEUE,
  payload: request,
});

export const clearOfflineQueue = () => ({
  type: CLEAR_QUEUE,
});

Reducer 实现

// src/reducers/offlineQueueReducer.js
import { ADD_TO_QUEUE, CLEAR_QUEUE } from '../actions/offlineActions';

const initialState = {
  requests: [],
};

const offlineQueueReducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_TO_QUEUE:
      return {
        ...state,
        requests: [...state.requests, action.payload],
      };
    case CLEAR_QUEUE:
      return { ...state, requests: [] };
    default:
      return state;
  }
};

export default offlineQueueReducer;

3. 编写带离线处理的API请求Thunk

在业务请求Thunk中加入网络判断,离线时将请求存入队列,在线时直接执行:

// src/thunks/apiThunks.js
import { addToOfflineQueue } from '../actions/offlineActions';
import { isConnected } from 'react-native-offline';

// 示例:创建帖子的请求Thunk
export const createPost = (postData) => async (dispatch) => {
  const connected = await isConnected();
  
  if (!connected) {
    // 离线时存储请求元信息,包含请求类型、参数
    dispatch(addToOfflineQueue({
      type: 'CREATE_POST',
      payload: postData,
      meta: { retry: true },
    }));
    return;
  }

  // 在线时发起真实请求
  try {
    const res = await fetch('https://your-api.com/posts', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(postData),
    });
    const data = await res.json();
    dispatch({ type: 'CREATE_POST_SUCCESS', payload: data });
  } catch (err) {
    dispatch({ type: 'CREATE_POST_FAILURE', payload: err.message });
  }
};

4. 网络恢复时执行离线队列

监听网络状态变化,当网络恢复时遍历队列执行请求:

队列执行Thunk

// src/thunks/offlineThunks.js
import { clearOfflineQueue } from '../actions/offlineActions';
import { createPost } from './apiThunks';

export const executeQueue = () => async (dispatch, getState) => {
  const { offlineQueue: { requests } } = getState();
  if (requests.length === 0) return;

  // 遍历队列,根据请求类型分发对应Thunk
  for (const req of requests) {
    switch (req.type) {
      case 'CREATE_POST':
        await dispatch(createPost(req.payload));
        break;
      // 扩展其他请求类型的处理逻辑
      default:
        break;
    }
  }

  // 执行完成后清空队列
  dispatch(clearOfflineQueue());
};

网络状态监听组件

// src/components/NetworkWatcher.js
import React, { useEffect } from 'react';
import { NetworkConsumer } from 'react-native-offline';
import { useDispatch } from 'react-redux';
import { executeQueue } from '../thunks/offlineThunks';
import { isConnected } from 'react-native-offline';

const NetworkWatcher = () => {
  const dispatch = useDispatch();

  // 组件挂载时检查网络,在线则执行队列
  useEffect(() => {
    (async () => {
      const connected = await isConnected();
      if (connected) dispatch(executeQueue());
    })();
  }, [dispatch]);

  return (
    <NetworkConsumer>
      {({ isConnected }) => {
        if (isConnected) dispatch(executeQueue());
        return null;
      }}
    </NetworkConsumer>
  );
};

export default NetworkWatcher;

最后在根组件中引入该监听组件:

// src/App.js
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './store';
import NetworkWatcher from './components/NetworkWatcher';

const App = () => {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <NetworkWatcher />
        {/* 你的业务组件 */}
      </PersistGate>
    </Provider>
  );
};

export default App;

关键注意事项

  • 请求幂等性:离线队列中的请求必须保证幂等(比如携带唯一请求ID),避免网络恢复后重复执行导致数据异常。
  • 错误重试:若队列中某个请求执行失败,可根据业务需求重新加入队列或标记错误状态。
  • 状态同步:执行队列后需同步更新本地Redux状态,确保离线操作的反馈和在线操作一致。

内容的提问来源于stack exchange,提问作者ViShU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:05:15