0.0.2 • Published 7 years ago

react-redux-async v0.0.2

Weekly downloads
5
License
MIT
Repository
github
Last release
7 years ago

react-redux-async

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

Installation

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

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

export default () =>
  <div>
    <h1>My App</h1>
    <MyComponent />
  </div>

To load MyComponent asynchronously:

App.js

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

export default () =>
  <div>
    <h1>My App</h1>
-   <MyComponent />
+   <Async load={() => import('./MyComponent')} />
  </div>

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

MyAsyncComponent.js

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

export default () => <Async load={() => import('./MyComponent')} />

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

App.js

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

export default () =>
  <div>
    <h1>My App</h1>
    <MyAsyncComponent />
  </div>

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

MyAsyncComponent.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 <Async load={load} />
}

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).

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

export default () =>
  <Async load={() => import('./MyComponent')}>
    <div>Loading...</div>
  </Async>

load: func

A function that should return a promise like 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, 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.

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

export default (props) =>
  <Async load={() => import('./MyComponent')} props={props} />

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

<MyAsyncComponent foo="bar" /> // <MyComponent foo="bar" />

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.

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

export default (props) =>
  <Async
    load={() => import('./MyComponent')}
    render={MyComponent => <MyComponent {...props} />}
  />

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:

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

export default () =>
  <div>
    <h1>My App</h1>
    <Route path="/foo" component={MyAsyncComponent} />
  </div>

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

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

export default () =>
  <div>
    <h1>My App</h1>
    <MyAsyncComponent render={() => null} />
    <Route path="/foo" component={MyAsyncComponent} />
  </div>

You should pass the render function to Async:

MyAsyncComponent.js

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

export default ({ render }) =>
  <Async load={() => 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