Skip to content

Commit

Permalink
done image-loader
Browse files Browse the repository at this point in the history
  • Loading branch information
chilijung committed Mar 7, 2018
1 parent 84e21e2 commit a493e48
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 46 deletions.
50 changes: 47 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,55 @@ $ npm install --save react-imgloader
## Usage

```js
var reactImgloader = require('react-imgloader');
class Demo extends React.Component {
constructor(props) {
super(props);

reactImgloader('Rainbow');
this.state = {
value: null
};
}

onChange = (e) => {
this.setState({
value: e.target.value
});
}

render() {
const {value} = this.state;
return (
<div>
<h1>Copy a image URL here</h1>
<input onChange={this.onChange}/>
<p>
value: {value}
</p>
<div>
{value && (
<ImageLoader
src={value}
loading={() => <div>Loading...</div>}
error={() => <div>Error</div>}
/>
)}
</div>
</div>
);
}
}
```

## Props

| Name | Type | Default | Description |
| ------------ | ------- | ------- | ----------- |
| src | string | null | Image URL |
| onLoad | (img: Image) => void | null | This function will be called when image is loaded |
| onError | (err: Event) => void | null | This function will be called when image is failed |
| loading | () => React.Element<*> | null | Return a React element that will show when image is loading |
| error | () => React.Element<*> | null | Return a React element that will show when image is crashed |

## Start example server

```
Expand All @@ -29,7 +73,7 @@ npm run gh-pages

## License

MIT © [chilijung]()
MIT © [chilijung](github.com/chilijung)


[npm-image]: https://badge.fury.io/js/react-imgloader.svg
Expand Down
4 changes: 2 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
</head>
<body>
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"></script>
<script src="./static/bundle.js"></script>
</body>
</html>
41 changes: 40 additions & 1 deletion docs/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,45 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ImageLoader from '../src';

class Demo extends React.Component {
constructor(props) {
super(props);

this.state = {
value: null
};
}

onChange = (e) => {
this.setState({
value: e.target.value
});
}

render() {
const {value} = this.state;
return (
<div>
<h1>Copy a image URL here</h1>
<input onChange={this.onChange}/>
<p>
value: {value}
</p>
<div>
{value && (
<ImageLoader
src={value}
loading={() => <div>Loading...</div>}
error={() => <div>Error</div>}
/>
)}
</div>
</div>
);
}
}

ReactDOM.render(
<div/>
<Demo/>
, document.getElementById('root'));
120 changes: 80 additions & 40 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,89 @@
// @flow
import React from 'react';
import Spinner from './Spinner';
import * as React from 'react';

export default class ImageLoader extends React.Component {
constructor(props) {
super(props);
type Props = {
src: string,
onLoad?: (img: Image) => void,
onError?: (err: Event) => void,
loading?: () => React.Element<*>,
error?: (err: Event) => React.Element<*>
}

type State = {
isLoading: boolean,
isError: boolean,
src: ?string,
errMsg: ?any,
}

this.state = {
isLoading: true,
src: ''
}
export default class ImageLoader extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
(this: any).reload = this.reload.bind(this);

this.state = {
isLoading: true,
isError: false,
src: null,
errMsg: null
}
}

componentWillReceiveProps(nextProps: Props) {
this.reload(nextProps);
}

componentDidMount() {
const image = new Image();
image.src = this.props.src;
image.onload = () => {
this.setState({
src: image.src,
isLoading: false
});
if (this.props.onLoad) {
this.props.onLoad(image);
}
};
image.onerror = (err) => {
this.setState({
src: '',
isLoading: false
});
if (this.props.onError) {
this.props.onError(err);
}
}
componentDidMount() {
this.reload(this.props);
}

reload(props: Props) {
// initialize
this.setState({
isLoading: true,
isError: false,
src: null,
errMsg: null
});

const image = new Image();
image.src = props.src;
image.onload = () => {
this.setState({
src: image.src,
isLoading: false,
isError: false,
errMsg: null
});
if (props.onLoad) {
props.onLoad(image);
}
};
image.onerror = (err) => {
this.setState({
src: null,
isLoading: false,
isError: true,
errMsg: err
});
if (props.onError) {
props.onError(err);
}
}
}

render() {
if (this.state.isLoading) {
return (
<Spinner src={this.props.spinnerSrc}/>
);
} else {
return (
<img className='ril--image' src={this.state.src} alt={this.props.alt} {...this.props}/>
);
}
render() {
const {loading, error} = this.props;
const {src, isLoading, isError, errMsg} = this.state;

if (loading && isLoading) {
return loading();
} else if (error && isError && errMsg) {
return error(errMsg);
} else if (src) {
return <img {...this.props} src={src}/>
}

return null;
}
}

0 comments on commit a493e48

Please sign in to comment.