rrr-lazy
=========================
Lazy load component with react && react-router.
[![CircleCI](https://circleci.com/gh/kouhin/rrr-lazy/tree/master.svg?style=svg)](https://circleci.com/gh/kouhin/rrr-lazy/tree/master)
[![dependency status](https://david-dm.org/kouhin/rrr-lazy.svg?style=flat-square)](https://david-dm.org/kouhin/rrr-lazy)
## Installationg
rrr-lazy requires **React 16.2.0 or later.**
For npm:
```
npm install rrr-lazy
```
For yarn:
```
yarn add rrr-lazy
```
IntersectionObserver is required by this library. You can use this polyfill for old browsers https://github.com/w3c/IntersectionObserver/tree/master/polyfill
## Usage
### Use as a common lazy component
```javascript
import React from 'react';
import { Lazy } from 'rrr-lazy';
const MyComponent = () => (
(
if (status === 'unload') {
return Unload
}
if (status === 'loading') {
return Loading
}
if (status === 'loaded') {
return (
')}`}
/>
);
}
throw new Error('Unknown status');
)}
/>
);
```
### Loading data or do something else with lifecycle hooks
```jsx
import { lazy } from 'rrr-lazy';
async function onLoading() {
// Loading data;
// ...
return data;
}
async function onLoaded() {
// Do something on loaded
// ...
return result;
}
async function onUnload() {
// Do something on unload
// ...
return result;
}
async function onError(error) {
// Do something on error
console.error(error);
// ...
return result;
}
class App extends React.Component {
render() {
// the matched child route components become props in the parent
return (
(
if (status === 'unload') {
return Unload
}
if (status === 'loading') {
return Loading
}
if (status === 'loaded') {
return (
')}`}
/>
);
}
throw new Error('Unknown status');
)}
onLoading={onLoading}
onLoaded={onLoaded}
onUnload={onUnload}
onError={onError}
/>
)
}
}
```
## API: ``
### Props
#### `root`
Type: `String|HTMLElement` Default: `null`
This value will be used as root for IntersectionObserver (See [root](https://www.w3.org/TR/intersection-observer/#dom-intersectionobserver-root).
#### `rootMargin`
Type: `String` Default: `null`
This value will be used as rootMargin for IntersectionObserver (See [rootMargin](https://www.w3.org/TR/intersection-observer/#dom-intersectionobserverinit-rootmargin).
#### `render(status, props)`
Type: `Function` **Required**
`status` can be `unload`, `loading`, `loaded`.
`props` are props that passed from `Lazy`. This is designed for `@lazy`, and when you use `` component, you may not need it.
#### `loaderComponent`
Type: `string` Default: `div`
#### `laoderProps`
Type: `string` Default: `{}`
`loaderComponent` and `loaderProps` is used to create a LoaderComponent when status is `unload` or `loaded`.
The result of `render(status, props)` will be passed to LoaderComponent as `children`.
#### onError()
#### onLoaded()
#### onLoading()
#### onUnload()
## API: `@lazy`
Usage:
``` javascript
@routerHooks({
fetch: async () => {
await fetchData();
},
defer: async () => {
await fetchDeferredData();
},
})
@lazy({
render: (status, props, Component) => {
if (status === 'unload') {
return Unload
;
} else if (status === 'loading') {
return Loading
;
} else {
return ;
}
},
onLoaded: () => console.log('look ma I have been lazyloaded!')
})
class MyComponent extends React.Component {
render() {
return (
);
}
}
```
Or
``` javascript
class MyComponent extends React.Component {
render() {
return (
);
}
}
const myComponent = lazy({
render: (status, props, Component) => {
if (status === 'unload') {
return Unload
;
} else if (status === 'loading') {
return Loading
;
} else {
return ;
}
},
onLoaded: () => console.log('look ma I have been lazyloaded!')
})(MyComponent);
```
### options
#### getComponent
With webpack 2 import()
``` javascript
const myComponent = lazy({
render: (status, props, Component) => {
if (status === 'unload') {
return Unload
;
} else if (status === 'loading') {
return Loading
;
} else {
return ;
}
},
onLoaded: () => console.log('look ma I have been lazyloaded!'),
getComponent: () => import('./MyComponent'),
})();
```
## API: LazyProvider
You can optionally use `LazyProvider` and pass a version (such as location) to the `value` prop.
All of the Lazy instances will be reset when version changed.
Example:
``` javascript
class Application extends React.Component {
render() {
// when pathname changed, all of the Lazy instances will be reset.
const { pathname, children } = this.state;
{ children }
}
}
```
## LICENSE
MIT