我正在尝试创建一个加载背景图像的组件(在同构应用程序中) . 虽然图像正在加载,但我想显示一个微调器但是我一直想出这个错误:
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.
在init时,加载状态设置为false(因此如果禁用js,则不显示微调器)
constructor (props) {
super(props);
this.state = {
loading: false
};
}
在componentDidMount上,加载状态设置为 true
,使用 props.src
创建图像,加载或错误调用函数时 .
componentDidMount = () => {
this.setState({loading: true});
this.image = new Image();
this.image.src = this.props.src;
this.image.onload = this.handleImageLoaded;
this.image.onerror = this.handleImageError;
}
这些函数会将加载状态设置为 false
handleImageLoaded = () => {
this.setState({loading: false});
}
handleImageError = () => {
this.setState({loading: false});
}
如果state为true(这会渲染),渲染函数将显示一个单独的组件 Loader
,我将更改img load上的内联样式背景 .
return (
<div className={style.wrapper}>
<div className={style.background} style='background-image:'>
<Loader loading={this.state.loading} />
</div>
</div>
);
2 回答
这是一个非常常见的问题,错误消息告诉您或多或少发生了什么 - 您试图在unmountedcomponent上调用
setState
. 在componentDidMount
中,您开始加载图像并设置回调(handleImageLoaded
)以在图像加载(或错误)时执行 . 在此回调中,您调用setState
. 由于加载是异步的,因此当组件不再在文档中时,它可以很容易地完成 .处理此问题的方法曾经是在修改状态之前询问组件是否仍然加载:
不幸的是,这会给你一个警告,说
isMounted()
已被弃用 . 你现在应该做的基本上是这样的:理想情况下,您只需取消
componentWillUnmount
中的加载,但我不能't think that' .另外,就像1ven所指出的那样,如果你在
componentWillUnmount
删除那些处理程序是个好主意,以防止任何潜在的内存泄漏 .在大多数情况下,在未安装的组件中调用
setState
时会显示此错误 .在您的情况下,据我所知,由于某种原因,您的组件在加载图像之前就已卸载 .
要避免此错误,您应该始终删除不在render函数中定义的任何事件侦听器,如下所示: