[英]Warning react : setState(…): Can only update a mounted or mounting component
Warning: setState(...): Can only update a mounted or mounting component. 警告:setState(...):只能更新已安装或正在安装的组件。 This usually means you called setState() on an unmounted component. 这通常意味着您在未安装的组件上调用了setState()。 This is a no-op. 这是无人值守。
This is a react application, where a banner is fixed on the screen and passing random images. 这是一个React应用程序,其中横幅广告固定在屏幕上并传递随机图像。 The way it was written is generating the warning in question. 它的编写方式正在生成有问题的警告。
import React from "react";
import Lightbox from "react-image-lightbox";
import logo from "./logo.png";
class Banner extends React.Component {
constructor(props) {
super(props);
this.state = {
images: [],
currentImage: logo,
isOpen: false,
sidebarOpen: true
};
}
async componentWillMount() {
await this.getBanners();
this.setState({ currentImage: this.state.images[0].url });
setInterval(async () => {
await this.getBanners();
}, 300000);
let i = 0;
setInterval(
() => {
this.setState({ currentImage: this.state.images[i].url });
if (i >= this.state.images.length - 1) {
i = 0;
} else {
i++;
}
},
10000,
i
);
}
async getBanners() {
const data = await (await fetch("/api/banners/active")).json();
if (data.true) {
this.setState({ images: data.true });
}
}
render() {
const { isOpen } = this.state;
return (
<div>
{isOpen && (
<Lightbox
mainSrc={this.state.currentImage}
onCloseRequest={() => this.setState({ isOpen: false })}
/>
)}
<footer>
<a>
<img
width={270}
height="200"
src={this.state.currentImage}
onClick={() => this.setState({ isOpen: true })}
alt="idk"
/>
</a>
</footer>
</div>
);
}
}
export default Banner;
Could anyone help improve this code? 有人可以帮助改善此代码吗?
You can put the numbers returned from setInterval
on your instance and stop the intervals with clearInterval
in componentWillUnmount
so that they won't continue to run after the component has been unmounted. 您可以将setInterval
返回的数字放在您的实例上,并在componentWillUnmount
使用clearInterval
停止间隔,以便在卸载组件后它们不会继续运行。
class Banner extends React.Component {
constructor(props) {
super(props);
this.bannerInterval = null;
this.currentImageInterval = null;
this.state = {
images: [],
currentImage: logo,
isOpen: false,
sidebarOpen: true
};
}
async componentDidMount() {
await this.getBanners();
this.setState({ currentImage: this.state.images[0].url });
this.bannerInterval = setInterval(async () => {
await this.getBanners();
}, 300000);
let i = 0;
this.currentImageInterval = setInterval(
() => {
this.setState({ currentImage: this.state.images[i].url });
if (i >= this.state.images.length - 1) {
i = 0;
} else {
i++;
}
},
10000,
i
);
}
componentWillUnmount() {
clearInterval(this.bannerInterval);
clearInterval(this.currentImageInterval);
}
// ...
}
Use this template for any class-based component that has a state: 将此模板用于任何具有状态的基于类的组件:
forgot about setState(), and use setComponentState declared down: 忘记了setState(),并使用向下声明的setComponentState:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
// other fields...
isUnmounted: false,
};
}
componentWillUnmount() {
this.setState({ isUnmounted: true });
}
setComponentState = (values) => {
if (!this.state.isUnmounted) this.setState(values);
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.