I am building a lazyloading component for images. But I have a problem with setting state. I'm getting Can only update a mounted or mounting component error, but I am using setState
inside componentDidMount
, which should allow me to avoid such errors.
Here's my code:
export default class Images extends React.Component {
constructor(props) {
super(props);
this.element = null;
this.state = {
loaded: false,
height: 0
};
}
componentDidMount() {
this.element = findDOMNode(this);
this.loadImage();
}
getDimensions() {
const w = this.element.offsetWidth;
let initw = 0;
let inith = 0;
let result;
const img = new Image();
img.src = this.props.url;
img.onload = (e) => {
initw = e.path[0].width;
inith = e.path[0].height;
result = (w / initw) * inith;
setTimeout(() => {
this.setState({
loaded: true,
height: `${result}px`
});
});
}
}
loadImage() {
_scrolling.add([this.element], () => {
if (this.element.classList.contains(_scrolling.classes.coming)) { // the image is visible
this.getDimensions();
}
});
}
render() {
const classes = this.state.loaded ? `${this.props.parentClass}__image--loaded` : null;
const styles = this.state.loaded ? {
maxHeight: this.state.height, minHeight: this.state.height, overflow: 'hidden'
} : null;
return (
<div className={`${this.props.parentClass}__image ${classes}`} style={styles}>
{this.state.loaded ?
<img
className={`${this.props.parentClass}__img`}
src={this.props.url}
title={this.props.title}
alt={this.props.title}
/>
: null
}
</div>
)
}
I belive the problem lies within img.onload
, but I don't know how to achieve this otherwise. What should I do?