如何在集成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
相关产品推荐
相关产品推荐

