It is simple redux middleware that helps you load redux initial state asynchronously
npm install redux-async-initial-stateRedux Async Initial State
=============
Redux middleware for async loading of initial app state.


``bash`
npm install --save redux-async-initial-state
With redux it is quite simple to synchronously load initial state, i.e. from localStorage:
`javascript`
...
const initialState = JSON.parse(localStorage.getItem('state'));
const store = storeCreator(reducer, initialState);
But it becomes quite complicated to do it asynchronously, i.e. from server or from async storage, like in React Native. This middleware do it for you.
1. Add package
`bash`
npm install --save redux-async-initial-state
2. Change your reducer and add middleware:
before:
`javascript
import { createStore, combineReducers } from 'redux'
import * as reducers from 'reducers'
const reducer = combineReducers(reducers)
const store = createStore(reducer)
`
After
`javascript
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import * as reducers from 'reducers';
import * as asyncInitialState from 'redux-async-initial-state';
// We need outerReducer to replace full state as soon as it loaded
const reducer = asyncInitialState.outerReducer(combineReducers({
...reducers,
// We need innerReducer to store loading state, i.e. for showing loading spinner
// If you don't need to handle loading state you may skip it
asyncInitialState: asyncInitialState.innerReducer,
}));
// Load state function
// Should return promise that resolves application state
const loadStore = () => {
return new Promise(resolve => {
fetch('/store')
.then(response => response.json())
.then(resolve);
});
}
const store = createStore(
reducer,
compose(applyMiddleware(asyncInitialState.middleware(loadStore)))
);
`
argument in loadStore function. So, if you have some complex shape of your reducer and you need to replace only some of keys in your store (currentUser in example below):`js
const loadStore = (getCurrentState) => {
return new Promise(resolve => {
fetch('/current_user.json')
.then(response => response.json())
.then(user => {
resolve({
// reuse state that was before loading current user
...getCurrentState(),
// and replace only currentUser key
currentUser: user
})
});
});
}
`Reducer
The shape of innerReducer is:`javascript
{
loaded: false,
loading: false,
error: false
}
`You can add it to you reducer if you want to handle loading state, i.e. to show loading spinner. Here is React example (it uses reducer, described above):
`javascript
import React from 'react';
import { connect } from 'react-redux';@connect(state => ({
loading: state.asyncInitialState.loading,
}))
class MyComponent extends React.Component {
render() {
if (this.props.loading) {
return
Loading...
}
return ...;
}
}
``