redux-offline-queue-too
v2.0.1
Published
Simple offline queue for redux, inspired by redux-offline-queue.
Downloads
2
Maintainers
Readme
redux-offline-queue-too
Forked from redux-offline-queue
made by InspireNL.
This package is a simple solution for handling actions or requests with redux while the app is in an offline state by queueing these, and dispatching them once connectivity is re-established. Works perfect with react-native
Motivation: Provide a better user experience.
Installation
npm install --save redux-offline-queue-too
Usage - NOTE: This won't apply to this repo, but for redux-offline-queue
See example project here: offlineTweet
Get up and running in 4 easy steps:
Step 1: Add the redux-offline-queue reducer to your combine reducers
Either import the { reducer as offlineQueue }
from redux-offline-queue
and add it to the combineReducers
or require it like so (whatever floats your boat):
import { combineReducers } from 'redux';
export default combineReducers({
offlineQueue: require('redux-offline-queue').reducer,
yourOtherReducer: require('~App/yourOtherReducer').reducer,
});
Step 2: Add the offlineMiddleware
import { offlineMiddleware } from 'redux-offline-queue';
const composeStoreWithMiddleware = applyMiddleware(offlineMiddleware())(
createStore
);
Note that this queue is not persisted by itself. One should provide a persistence config by using e.g. redux-persist
to keep the offline queue persisted.
Step 3: Declare the actions to be queued
With reduxsauce
import { createReducer, createActions } from 'reduxsauce'
import { markActionsOffline } from 'redux-offline-queue'
const { Types, Creators } = createActions({
requestBlogs: null,
createBlog: ['blog'],
})
markActionsOffline(Creators, ['createBlog'])
...
Without
import { markActionsOffline } from 'redux-offline-queue'
const Creators = {
createBlog: blog => ({
type: 'CREATE_BLOG',
blog,
}),
}
markActionsOffline(Creators, ['createBlog'])
...
Last but not least...
Step 4: Monitor the connectivity and let the library know.
import { OFFLINE, ONLINE } from 'redux-offline-queue';
if (appIsConnected) {
dispatch({ type: ONLINE });
} else {
dispatch({ type: OFFLINE });
}
Works perfect with React Native's NetInfo
import { put, take, call } from 'redux-saga/effects';
import { NetInfo } from 'react-native';
import { OFFLINE, ONLINE } from 'redux-offline-queue';
function* startWatchingNetworkConnectivity() {
const channel = eventChannel(emitter => {
NetInfo.isConnected.addEventListener('connectionChange', emitter);
return () =>
NetInfo.isConnected.removeEventListener('connectionChange', emitter);
});
try {
for (;;) {
const isConnected = yield take(channel);
if (isConnected) {
yield put({ type: ONLINE });
} else {
yield put({ type: OFFLINE });
}
}
} finally {
channel.close();
}
}
Android
If react native's NetInfo
is intended to be used, for android don't forget to add the following to the AndroidManifest.xml
:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Inspired by redux-queue-offline(mathieudutour)
Developed by Krzysztof Ciombor
Compatibility
with redux-saga
If you are using redux-sagas
for http requests and want to fire your redux actions normally, but suspend(queue) sagas, for Step 2, do the following instead:
import { applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import {
offlineMiddleware,
suspendSaga,
consumeActionMiddleware,
} from 'redux-offline-queue';
const middleware = [];
middleware.push(offlineMiddleware());
const suspendSagaMiddleware = suspendSaga(createSagaMiddleware());
middleware.push(suspendSagaMiddleware);
middleware.push(consumeActionMiddleware());
applyMiddleware(...middleware);
It is IMPORTANT that the consumeActionMiddleware
is placed last, so you can allow the previous middlewares to react first before eventually getting consumed.
Additional Configuration
Additional configuration can be passed with offlineMiddleware()
, such as adding additional triggers that will trigger the offline queue to dispatch its actions:
...
import { REHYDRATE } from 'redux-persist'
applyMiddleware(offlineMiddleware({
additionalTriggers: REHYDRATE,
}))
...