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

https://github.com/marella/react-redux-async

Load react components and redux reducers asynchronously. Useful for code splitting and lazy loading.
https://github.com/marella/react-redux-async

async async-components async-reducers code-splitting lazy-loading react redux

Last synced: 11 months ago
JSON representation

Load react components and redux reducers asynchronously. Useful for code splitting and lazy loading.

Awesome Lists containing this project

README

          

# react-redux-async

Load react components and redux reducers asynchronously. Useful for code splitting and lazy loading.

- [Installation](#installation)
- [Example](#example)
- [Documentation](#documentation)
- [API](#api)
- [React Router](#react-router)
- [Preload](#preload)
- [License](#license)

## Installation

```bash
npm install react-redux-async --save
```

## Example

> Most of these examples use [Functional Components] and ES6 syntax.

Let's say you have a component `MyComponent`:

*App.js*

```js
import React from 'react'
import MyComponent from './MyComponent'

export default () =>


My App




```

To load `MyComponent` asynchronously:

*App.js*

```diff
import React from 'react'
-import MyComponent from './MyComponent'
+import Async from 'react-redux-async'

export default () =>


My App


-
+ import('./MyComponent')} />

```

`MyComponent` will automatically render after it is loaded. Alternatively you can also create a separate "async component":

*MyAsyncComponent.js*

```js
import React from 'react'
import Async from 'react-redux-async'

export default () => import('./MyComponent')} />
```

Now you can use this async component like a normal component:

*App.js*

```js
import React from 'react'
import MyAsyncComponent from './MyAsyncComponent'

export default () =>


My App




```

You can also load redux reducers asynchronously. Redux `store` is passed as the first argument to `load` function:

*MyAsyncComponent.js*

```js
import React from 'react'
import Async from 'react-redux-async'

export default () => {
const load = async store => {
// Load your component asynchronously
// but don't "wait" for it to load.
const component = import('./MyComponent')

// Load your reducer(s) asynchronously
// and "wait" for them to load.
const reducer = await import('./reducer')

// TODO: Here use store.replaceReducer() to add the new reducer(s).

// "Wait" for the component to load.
// This way both component and reducer(s) can be loaded in parallel.
return await component
}

return
}
```

## Documentation

### API

#### `children: node` - Loading State

You can pass a loader/spinner through `children` which will be rendered before the component is loaded (promise returned by `load` function is resolved).

```js
import React from 'react'
import Async from 'react-redux-async'

export default () =>
import('./MyComponent')}>

Loading...


```

#### `load: func`

A function that should return a promise like [`import()`][import()]. The promise should return a module object or component when resolved. `load` function will be called only after `Async` has mounted.

> **NOTE:** If you want to support older browsers that lack Promise support, you'll need to include a Promise polyfill.

When `store` is available through `props` or [`context`][context], it will be passed as the first argument to `load` function. You can use it to add reducers dynamically to store. See previous examples.

#### `props: object`

`props` that should be passed to the component that will be loaded.

```js
import React from 'react'
import Async from 'react-redux-async'

export default (props) =>
import('./MyComponent')} props={props} />
```

Now you can pass `props` to the async component as if you were passing them to the actual component.

```js
//
```

#### `render: func`

A function to render the loaded component. Loaded component will be passed as the first argument. Return value of the `render` function will be rendered.

```js
import React from 'react'
import Async from 'react-redux-async'

export default (props) =>
import('./MyComponent')}
render={MyComponent => }
/>
```

### React Router

Since `load` function will be called only after `Async` has mounted, you can use it with [react-router] v4 to lazy load components:

```js
import React from 'react'
import { Route } from 'react-router'
import MyAsyncComponent from './MyAsyncComponent'

export default () =>


My App




```

Here `MyComponent` is loaded by `MyAsyncComponent` only when URL path matches `'/foo'`.

### Preload

You can preload a component without rendering it by returning `null` in `render` function of `Async`:

*App.js*

```js
import React from 'react'
import { Route } from 'react-router'
import MyAsyncComponent from './MyAsyncComponent'

export default () =>


My App


null} />


```

You should pass the `render` function to `Async`:

*MyAsyncComponent.js*

```js
import React from 'react'
import Async from 'react-redux-async'

export default ({ render }) =>
import('./MyComponent')} render={render} />
```

Here `MyAsyncComponent` will start loading `MyComponent` as soon as `App` is rendered. But `MyComponent` will not be rendered until the URL path matches `'/foo'`.

Passing `null` or `undefined` to `render` will not have any effect and the loaded component will be rendered normally.

## License

[MIT][license]

[license]: /LICENSE
[Functional Components]: https://facebook.github.io/react/docs/components-and-props.html#functional-and-class-components
[context]: https://facebook.github.io/react/docs/context.html
[react-router]: https://github.com/ReactTraining/react-router
[import()]: https://webpack.js.org/api/module-methods/#import-