我从应用程序中的多个组件中收到以下错误。
警告:无法在已卸载的组件上调用setState(或forceUpdate)。这是空操作,但它表明应用程序中发生内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。
导致此问题的组件之一在componentWillUnmount方法中具有调整大小的remove事件侦听器。我该如何解决此问题。从我在在线示例中看到的情况来看,通常使用这种方法取消订阅事件。
不允许粘贴特定代码,因此我正在编写伪代码
clickHandler() {
this.setState({ opened: !(this.state.opened) });
}
componentDidMount() {
this.setState({ width: window.innerWidth } );
window.addEventListener('resize', this.updateWidth);
}
componentWillUnmount() {
window.removeEventListener('resize', this.updateWidth);
}
private updateWidth() {
if (this.state.opened &&
window.innerWidth >= someMethodReturnsViewportConstant()) {
this.onClickHandler();
const htmlElement: HTMLInputElement =
document.querySelector('#html-element-id');
if (htmlElement && htmlElement) {
htmlElement = false;
}
}
}
我所做的:
我已经阅读了Stack上与此有关的所有文章,但都没有解释为什么我的代码导致了这个问题。
答案 0 :(得分:0)
由于您没有共享太多代码,因此我认为以下是您正在做的事情
this.updateWidth = setTimeout(() => {
this.setState({
width:100
});
}, 3000);
componentWillUnmount() {
clearTimeout(this.updateWidth);
}
所以无论您在setTimeout中进行seState还是在我提到的componentWillUnMount中清除它们
此外,如果您使用componentWillReceiveProps或componentDidUpdate,则需要使用nextProps或nextState检查当前道具或状态,如果它们不相等,则执行setState。此检查是强制性的。这也是您面临无限警告的原因
答案 1 :(得分:0)
正如其他人所说,您没有提供足够的代码来查看实际发生的情况。
但是,您可以做的是添加一个标志,以查看组件是否已卸载,以防止状态更新。
这是一个例子。
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
exampleState: []
};
this.isUnmounted = false;
this.updateState = this.updateState.bind(this);
}
componentWillUnmount() {
this.isUnmounted = true;
}
updateState() {
if (!this.isUnmounted) { // Don't allow state change if component is unmounted
this.setState({ exampleState: [1, 2, 3] });
}
}
}
现在您有了一个标志,可以用来调试状态更改。仔细检查您的组件状态是否会一次更改,最终您将发现警告的来源。