# redux-async-initial-state

> It is simple redux middleware that helps you load redux initial state asynchronously

Latest version **0.3.0** (published 2018-06-13) · MIT license · 0 weekly downloads

## Install

```sh
npm install redux-async-initial-state
pnpm add redux-async-initial-state
yarn add redux-async-initial-state
bun add redux-async-initial-state
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.3.0 |
| Published | 2018-06-13 |
| First published | 2016-03-02 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 9.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 113 |
| Author | KELiON |
| Maintainers | kelion |
| Keywords | redux, initial, state, async |

## Links

- npm: https://www.npmjs.com/package/redux-async-initial-state
- Repository: https://github.com/KELiON/redux-async-initial-state
- Homepage: https://github.com/KELiON/redux-async-initial-state#readme
- Issues: https://github.com/KELiON/redux-async-initial-state/issues
- npm.io page: https://npm.io/package/redux-async-initial-state

## Alternatives

- [@reckona/mreact-store](https://npm.io/package/@reckona/mreact-store.md) — 976 weekly downloads
- [regular-state](https://npm.io/package/regular-state.md) — 410 weekly downloads
- [@pacote/flux-actions](https://npm.io/package/@pacote/flux-actions.md) — 65 weekly downloads
- [@pilotlab/lux-debug](https://npm.io/package/@pilotlab/lux-debug.md) — 39 weekly downloads
- [vue-persist-state](https://npm.io/package/vue-persist-state.md) — 19 weekly downloads

## Recent versions

- 0.3.0 (latest) — 2018-06-13
- 0.0.2 (beta) — 2016-03-02
- 0.2.2 — 2018-05-11
- 0.2.1 — 2017-07-31
- 0.2.0 — 2016-10-13
- 0.1.2 — 2016-06-06
- 0.1.1 — 2016-03-03
- 0.1.0 — 2016-03-03
- 0.0.1 — 2016-03-02

## README

Redux Async Initial State
=============

Redux [middleware](http://redux.js.org/docs/advanced/Middleware.html) for async loading of initial app state.

[![build status](https://img.shields.io/travis/KELiON/redux-async-initial-state/master.svg?style=flat-square)](https://travis-ci.org/KELiON/redux-async-initial-state)
[![npm version](https://img.shields.io/npm/v/redux-async-initial-state.svg?style=flat-square)](https://www.npmjs.com/package/redux-async-initial-state)


```bash
npm install --save redux-async-initial-state
```

## What? Why?

With [redux](http://redux.js.org) 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](https://facebook.github.io/react-native/docs/asyncstorage.html). This middleware do it for you.

## Usage

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)))
);
```

### Partial replace
In case when you're loading only part of your store initially, you can add `getCurrentState` 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 <div>Loading...</div>
    }
    return ...;
  }
}
```

---
_Source: https://npm.io/package/redux-async-initial-state · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
