我有一个反应应用程序,我使用另一个名为load-image
的组件加载图像。
现在我将src
传递给load-image
,它显示了一个很好的加载器,直到图像加载,加载后,它会显示一个漂亮的图像动画。
问题出在这里。我打开了应用页面,所有图片都开始加载。 现在用户转到另一个页面,图像仍在加载。我可以在控制台中看到它们加载。现在我在控制台中收到此错误。
警告:setState(...):只能更新已安装或已安装 零件。这通常意味着您在已卸载时调用了setState() 零件。这是一个无操作。请检查未定义的代码 成分
这是我的代码。
export default class LoadImage extends React.Component {
constructor() {
super();
this.state = {
isLoaded: false,
isMounted: false,
};
this.onImageLoad = this.onImageLoad.bind(this);
}
componentDidMount() {
const imgSrc = this.props.imageSrc;
const img = new window.Image();
img.onload = this.onImageLoad;
img.src = imgSrc;
this.setState({
isMounted: true,
});
}
componentWillUnmount() {
this.setState({
isMounted: false,
});
}
onImageLoad() {
const self = this;
if (self.state.isMounted === true) {
self.setState({
isLoaded: true,
});
}
}
render() {
const self = this;
const imageClasses = classNames({
'image-loaded': self.state.isLoaded,
'image': true,
});
const imgStyle = {
backgroundImage: 'url("' + self.props.imageSrc + '")',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
width: 'inherit',
height: 'inherit',
};
return (
<div className="image-loader">
<div style={ imgStyle } className={ imageClasses }>
</div>
</div>
);
}
}
如何取消旧请求,以便他们在卸载后不会更新状态。我已经使用state来检查组件是否已安装。谢谢。
答案 0 :(得分:5)
您可以在图片仍在加载时更改回调。在componentWillUnmount
中,将this.img.onload
设置为不执行任何操作的函数。
componentDidMount() {
const imgSrc = this.props.imageSrc;
this.img = new window.Image();
this.img.src = imgSrc;
this.img.onload = this.onImageLoad;
}
componentWillUnmount() {
if ( ! this.img ) {
return;
}
this.img.onload = function(){};
delete this.img;
}
来源: https://github.com/Automattic/wp-calypso/blob/master/client/components/image-preloader/index.jsx
如果采用这种方法,则不需要isMounted()。
答案 1 :(得分:1)
Don't call setState
in componentWillUnmount
. If the component is about to unmount, there's no point altering its state since it's about to be removed from the DOM.