我一直在研究一个组件,它需要在页面调整大小时跟踪页面的宽度。然而,我能够做到这一点,但react一直向我抛出一个错误。
这是它抛出的错误:
warning.js:36 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.
Please check the code for the Nav component.
堆栈跟踪指向的导致错误的代码是Nav
组件上的handleResize()
方法。在做了一点搜索和谷歌搜索之后,我发现原因是setState()
在组件安装之前被调用。这很奇怪,因为事件侦听器是在componentDidMount()
中注册的。一篇文章建议使用componentWillMount
No cigar。我不太确定为什么会这样。也许是因为调整大小的速度太快了?
handleResize() {
this.setState((prevState, currProps) => ({
height: window.innerHeight,
width: window.innerWidth
}));
if (this.props.showMenu === undefined) {
if (this.state.width > (this.props.breakPoint || 767) && this.state.showMenu) {
this.setState((prevState, currProps) => ({
showMenu: false,
}));
}
} else {
if (this.state.width > (this.props.breakPoint || 767) && this.props.showMenu) {
this.props.closeMenu();
}
}
}
componentDidMount () {
window.addEventListener('resize', this.handleResize.bind(this));
}
componentWillUnmount () {
window.removeEventListener('resize', this.handleResize.bind(this))
}
this.handleResive.bind(this)
创建了一个新函数,这意味着window.removeEventListener('resize', this.handleResize.bind(this))
也创建了一个新函数,而不是传递您首先添加的相同函数。这意味着您之前使用bind创建并添加的函数不会被删除,因为它不是相同的函数(尽管它的行为完全相同)。解决这个问题的一种方法是在添加函数之前存储函数:
componentDidMount () {
const resizeHandler = this.handleResize.bind(this);
this.setState({resizeHandler});
window.addEventListener('resize', resizeHandler);
}
componentWillUnmount () {
window.removeEventListener('resize', this.state.resizeHandler);
//you could cleanup state here but it's not necessary
}
如果有人有更好的方法来存储事件处理函数,请加入。