Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/recruit-tech/redux-async-loader

Async data loader for Redux apps.
https://github.com/recruit-tech/redux-async-loader

Last synced: 24 days ago
JSON representation

Async data loader for Redux apps.

Awesome Lists containing this project

README

        

# redux-async-loader

Async data loader for Redux apps with React-Router.

## CAUTION

`redux-async-loader` is incompatible with `react-redux@5`

For `react-redux@5`, you neeed to use the 1.x release of redux-async-loader.

## Installation

```
npm install --save redux-async-loader
```

## Usage

### 1. Register Reducer

```javascript
import { combineReducers, createStore } from 'redux';
import { reduxAsyncLoader } from 'redux-async-loader';

const store = createStore(combineReducers({
reduxAsyncLoader,
...
}), initialState);
```

### 2. Server-Side Rendering (Optional)

```javascript
import { applyRouterMiddleware, match, RouterContext } from 'react-router';
import { loadOnServer } from 'redux-async-loader';

match({ history, routes }, (error, redirectLocation, renderProps) => {
// ...

loadOnServer(renderProps, store).then(() => {
const content = renderToString(



);
});
});
```

### 3. Client-Side Rendering

```javascript
import { render } from 'react-dom';
import { Router, applyRouterMiddleware, browserHistory } from 'react-router';
import { useAsyncLoader } from 'redux-async-loader';

const RenderWithMiddleware = applyRouterMiddleware(
useAsyncLoader(),
);

render(

} />

, el);
```

If you are using
[react-router-scroll](https://github.com/taion/react-router-scroll),
it should be applied *after* redux-async-loader.

```javascript
import useScroll from 'react-router-scroll';

const RenderWithMiddleware = applyRouterMiddleware(
useAsyncLoader(),
useScroll()
);
```

### 4. Async data loading by routing (both client and server-side rendering)

```javascript
import { connect } from 'react-redux';
import { asyncLoader } from 'redux-async-loader';

class UserList extends React.Component {
// ...
}

export default asyncLoader((props, store) => store.dispatch(loadUsers(props)))(
connect({ ... }, { ... })(
UserList
)
);
```

or, with
[decorator](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy):

```javascript
@asyncLoader((props, store) => store.dispatch(loadUsers(props)))
@connect({ ... }, { ... })
export default class UserList extends React.Component {
// ...
}
```

or, with
[recompose](https://github.com/acdlite/recompose):

```javascript
import { compose } from 'recompose';

export default compose(
asyncLoader((props, store) => store.dispatch(loadUsers(props))),
connect({ ... }, { ... })
)(class UserList exptends React.Component {
// ...
});
```

Unlike
[redux-async-connect](https://www.npmjs.com/package/redux-async-connect),
redux-async-loader itself doesn't connect to store.
You have to call
[connect()](https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)
explicitly if you want to use store's state.

If you want to invoke `asyncLoader()` when just querystring (not path) is changed, you must specify key names of querystring to router.

```

```

Or, you can use the wildcard for any keys of querystring:

```

```

### 5. Async data loading by mounting/updating (client-side rendering only)

```javascript
import { connect } from 'react-redux';
import { deferLoader } from 'redux-async-loader';

class UserList extends React.Component {
// ...
}

export default deferLoader((props, store) => store.dispatch(loadUsers(props)))(
connect({ ... }, { ... })(
UserList
)
);
```

or, with
[decorator](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy):

```javascript
@deferLoader((props, store) => store.dispatch(loadUsers(props)))
@connect({ ... }, { ... })
export default class UserList extends React.Component {
// ...
}
```

or, with
[recompose](https://github.com/acdlite/recompose):

```javascript
import { compose } from 'recompose';

export default compose(
deferLoader((props, store) => store.dispatch(loadUsers(props))),
connect({ ... }, { ... })
)(class UserList exptends React.Component {
// ...
});
```

## API

#### `asyncLoader(loader)`

Creates Higher-order Component for async data loading by routing.

##### Arguments

* `loader` *(Function)*: Called when this component is routed.
* Arguments
* `props` *(Object)*: The props passed from React-Router.
See
[React-Router API docs](https://github.com/reactjs/react-router/blob/master/docs/API.md#proptypes)
for more info.
* `store`: *(Object)*: Redux's store object.
* Returns
* *(Promise)*: Fulfilled when data loading is completed.

##### Returns

* *(Function)*: Creates higher-order component.
* Arguments
* wrappedComponent *(Component)*: Wrapped component.
* Returns
* *(Component)*: Wrapper component.

#### `deferLoader(loader)`

Creates Higher-order Component for async data loading by mounting and updating.

##### Arguments

* `loader` *(Function)*: Called when this component is mounted or updated.
* Arguments
* `props` *(Object)*: The props passed from parent component.
* `store`: *(Object)*: Redux's store object.
* Returns
* *(Promise)*: Fulfilled when data loading is completed.

##### Returns

* *(Function)*: Creates higher-order component.
* Arguments
* wrappedComponent *(Component)*: Wrapped component.
* Returns
* *(Component)*: Wrapper component.

#### `loadOnServer(renderProps, store)`

Loads async data on the server side.

##### Arguments

* `renderProps` *(Object)*: The props passed via `match()`'s callback.
See
[React-Router API docs](https://github.com/reactjs/react-router/blob/master/docs/API.md#match-routes-location-history-options--cb)
for more info.
* `store` *(Object)*: Redux's store object.

##### Returns

* *(Promise)*: Fulfilled when data loading is completed.