Created
April 16, 2017 22:14
-
-
Save gabemeola/69b5338aec4a5e234ac9f6c7dffdf8a8 to your computer and use it in GitHub Desktop.
Initializing React Application with async data loading, and persisting data to user device local storage with redux-persist and localForage.
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 in React Project files */ | |
import React, { Component } from 'react'; | |
import ReactDOM from 'react-dom'; | |
import { Provider } from 'react-redux'; | |
import thunk from 'redux-thunk'; | |
import { combineReducers, compose, applyMiddleware, createStore } from 'redux'; | |
import { persistStore, autoRehydrate } from 'redux-persist'; | |
import localForage from 'localforage'; | |
/* Import Routes and App Data */ | |
import getRoutes from './config/routes'; | |
import * as formReducers from 'redux/modules/form'; | |
import { getFormAPI, formatFormAPIData } from 'utils/api'; | |
import { LoadingSplash } from 'components/Injectables'; | |
async function getFormAPIData() { | |
// XHR Request wrapped in Async Promise for to always be resolved | |
// in case of no connect to server | |
try { | |
const { data } = await getFormAPI(); | |
return formatFormAPIData(data); | |
} catch (err) { | |
console.error('Get Form Api Error', err); | |
// Return Undefined if no data or error so user can still use internal redux store | |
return undefined; | |
} | |
} | |
// Configuring Redux Store | |
const initStore = async () => createStore( | |
combineReducers({ | |
form: combineReducers(formReducers), | |
}), | |
{form: await getFormAPIData()}, | |
compose( | |
// Redux Thunks that lets us return function asynchronously | |
applyMiddleware(thunk), | |
// Auto Merges Redux Device Storage from redux-persist | |
autoRehydrate(), | |
// Lets us view Redux store using Redux Chrome Extension | |
// if we are not running in production | |
process.env.NODE_ENV !== 'production' | |
? window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f | |
: f => f | |
) | |
); | |
// Delay Rendering until App is Rehydrated from redux-persist | |
class AppProvider extends Component { | |
constructor() { | |
super(); | |
this.state = { | |
rehydrated: false, | |
store: null, | |
}; | |
} | |
componentWillMount() { | |
initStore().then(store => { | |
console.log('store', store); | |
this.bootstrapStore(store); | |
}); | |
} | |
bootstrapStore = (store) => { | |
persistStore(store, { storage: localForage }, (err, state) => { | |
if(err) return console.warn('persistStore', err); | |
console.info('Rehydration Complete', state); | |
this.setState({ | |
rehydrated: true, | |
store: store, | |
}); | |
}); | |
} | |
render() { | |
if(!this.state.rehydrated) { | |
return <LoadingSplash/> | |
} | |
return( | |
<Provider store={this.state.store}> | |
{getRoutes(this.state.store.getState)} | |
</Provider> | |
) | |
} | |
} | |
/* Bootstrap React to the page */ | |
ReactDOM.render( | |
<AppProvider/>, | |
document.getElementById('app') | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment