Skip to content

Instantly share code, notes, and snippets.

@gabemeola
Created April 16, 2017 22:14
Show Gist options
  • Save gabemeola/69b5338aec4a5e234ac9f6c7dffdf8a8 to your computer and use it in GitHub Desktop.
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.
/* 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