I have a react component I am using to load my images progressively for my app which has been working great for me. When I use it on a page to load images, though, I am seeing an error:
warning.js:35 Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op.
Multiple times - looks like once for each image called. It does not seem to be effecting anything seriously as the image components still work. I am wondering how to get rid of this error though, I cannot figure out how.
So here is my component:
import React, { PropTypes } from 'react';
require('./progressive-image.scss');
export default class ProgressiveImage extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false,
image: props.smallImg
};
this.loadImage = this.loadImage.bind(this);
this.onLoad = this.onLoad.bind(this);
this.onError = this.onError.bind(this);
this.image = undefined;
}
componentDidMount() {
const { largeImg } = this.props;
this.loadImage(largeImg);
}
onError(err) {
console.warn('Error loading progressive image :', err);
}
onLoad() {
this.setState({
loaded: true,
image: this.image.src
});
}
componentDidUpdate(nextProps) {
const { largeImg, smallImg } = nextProps;
if (largeImg !== this.props.largeImg) {
this.setState({ loaded: false, image: smallImg }, () => {
this.loadImage(largeImg);
});
}
}
loadImage(src) {
if (this.image) {
this.image.onload = null;
this.image.onerror = null;
}
const image = new Image();
this.image = image;
image.onload = this.onLoad;
image.onerror = this.onError;
image.src = src;
}
render() {
const imgStyle = { 'paddingBottom': this.props.heightRatio };
const { imgAlt, imgTitle } = this.props;
return (
<div className={`progressive-placeholder ${this.state.loaded ? 'loaded' : ''}`}>
{this.state.loaded &&
<img
alt={imgAlt}
className={`loaded`}
src={this.state.image}
title={imgTitle}
/>
}
<img className={`img-small ${!this.state.loaded ? 'loaded' : ''}`} src={this.state.image} alt="placeholder image for loading"/>
<div style={imgStyle} ></div>
</div>
);
}
}
ProgressiveImage.displayName = 'ProgressiveImage';
ProgressiveImage.propTypes = {
bgColor: PropTypes.string,
heightRatio: PropTypes.string.isRequired,
largeImg: PropTypes.string.isRequired,
smallImg: PropTypes.string.isRequired,
imgAlt: PropTypes.string,
imgTitle: PropTypes.string,
};
So the only time setState is called is when onLoad
or componentDidUpdate
is called. My thinking is that because its only called did mount and did update it should not be getting this error. Looking for any insight on how to clean up this error, as it has me puzzled. If any additional info is needed, I am happy to provide.
The problem is your callback in image.onload
could be called at any random point :
image.onload = this.onLoad;
Chances are this.onLoad
is being called while your component is rendering.
The problem is that because this.onLoad
is called when your external image resource loads then when you are doing this.setState
, your component could be rendering and this would cause the error .
To handle this I would recommend setting the loaded
/ image
values outside of the local Component
state and instead dispatch
it to a global state using something like redux
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.