Last active
January 18, 2021 11:27
-
-
Save jfbloom22/6ef92d9ff28007be8ce1154d28e7c66e to your computer and use it in GitHub Desktop.
redux configure store with redux-thunk, redux-offline, redux-persist v5, localForage, redux-devtools-extension, redux-immutable-state-invariant, axios, and typescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
applyMiddleware, | |
createStore, | |
Middleware, | |
Store, | |
AnyAction, | |
compose | |
} from 'redux'; | |
import { createOffline } from '@redux-offline/redux-offline'; | |
// use redux-persist v5 because it has built in support for migrations | |
import { persistStore, persistReducer } from 'redux-persist'; | |
import axios, { AxiosRequestConfig, AxiosError } from 'axios'; | |
import * as localForage from 'localforage'; | |
import offlineConfig from '@redux-offline/redux-offline/lib/defaults/index'; | |
import thunk, { ThunkMiddleware } from 'redux-thunk'; | |
import { IinitialState } from '../constants/models'; | |
import constants from '../constants/constants'; | |
import rootReducer from '../reducers'; | |
const effect = ( | |
{ | |
axiosRequest, | |
message | |
}: { axiosRequest: AxiosRequestConfig; message: string }, | |
action: any | |
) => | |
axios(axiosRequest).catch(err => { | |
console.error(message, err); | |
constants.handleError(err, message); | |
throw err; | |
}); | |
// if discard returns true, then it will try again | |
const discard = (error: AxiosError, action: any, retries: number) => { | |
const { request, response } = error; | |
if (!request) { | |
throw error; | |
} // There was an error creating the request | |
if (!response) { | |
return false; | |
} // There was no response | |
return 400 <= response.status && response.status < 500; // if it is a 400 error then discard | |
}; | |
const persistConfig = { | |
key: 'state-core-care-app_', | |
debounce: 500, | |
storage: localForage | |
}; | |
const { | |
middleware: offlineMiddleware, | |
enhanceReducer: offlineEnhanceReducer, | |
enhanceStore: offlineEnhanceStore | |
} = createOffline({ | |
...offlineConfig, | |
persist: false, | |
effect, | |
discard | |
}); | |
const persistedReducer = persistReducer( | |
persistConfig, | |
offlineEnhanceReducer(rootReducer) | |
); | |
export default function configureStore() { | |
if (process.env.NODE_ENV !== 'production') { | |
const store = createStore( | |
persistedReducer, | |
require('redux-devtools-extension').composeWithDevTools( | |
offlineEnhanceStore, | |
applyMiddleware( | |
thunk as ThunkMiddleware<IinitialState, any>, | |
require('redux-immutable-state-invariant').default(), | |
offlineMiddleware as Middleware<any, any, any> | |
) | |
) | |
) as Store<any, AnyAction>; | |
const persistor = persistStore(store); | |
return { persistor, store }; | |
} | |
else { | |
const store = createStore( | |
persistedReducer, | |
compose( | |
applyMiddleware(thunk as ThunkMiddleware<IinitialState, any>), | |
offlineMiddleware as Middleware<any, any, any> | |
) | |
) as Store<any, AnyAction>; | |
const persistor = persistStore(store); | |
return { persistor, store }; | |
} | |
} |
Created a more advanced config which adds a helper for persisting date objects, config for the persist reducer, and sections to help improve redux-devtools performance. https://gist.github.com/jfbloom22/093a75419db378cf42862ee11375903b
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
switched to localForage and upgraded to redux-persist v5 because it supports redux migrations. The above configuration also expects you to change the main App render statement to use PersistGate like so:
see redux-persist docs for more info: https://github.com/rt2zz/redux-persist#basic-usage