我正在尝试setState(),以便在调整窗口大小时,将不同屏幕尺寸的不同数量的项目设置为组件状态。我在组件安装时添加了一个事件监听器,并在卸载时将其删除。
componentDidMount()
{
this.updateValue();
window.addEventListener("resize", this.updateValue.bind(this));
}
updateValue()
{
var windowWidth = window.screen.width;
if(windowWidth <= 991 && windowWidth >= 768){
this.setState({ items:6 })
} else if(windowWidth <= 767 && windowWidth >= 479){
this.setState({ items:4 })
} else if( windowWidth < 480 && windowWidth >= 359){
this.setState({ items:2 })
} else if( windowWidth < 360){
this.setState({ items: 2})
} else {
this.setState({items:12})
}
}
componentWillUnmount()
{
window.removeEventListener("resize", this.updateValue.bind(this));
}
当我在安装组件的路线中时工作正常;直到我通过打开另一条路径离开组件并调整窗口大小,当我收到错误时:
警告:setState(...):只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作。请检查FeaturedRestaurants组件的代码。
当我调整屏幕大小时,我会在一秒内得到一百个错误。
显然,removeEventListener不起作用。我哪里出错了?
答案 0 :(得分:4)
尝试执行以下操作:
componentDidMount()
{
this.updateValue();
window.addEventListener("resize", this.updateValue);
}
updateValue = () =>
{
var windowWidth = window.screen.width;
if(windowWidth <= 991 && windowWidth >= 768){
this.setState({ items:6 })
} else if(windowWidth <= 767 && windowWidth >= 479){
this.setState({ items:4 })
} else if( windowWidth < 480 && windowWidth >= 359){
this.setState({ items:2 })
} else if( windowWidth < 360){
this.setState({ items: 2})
} else {
this.setState({items:12})
}
}
componentWillUnmount()
{
window.removeEventListener("resize", this.updateValue);
}
您必须将与第二个参数相同的函数传递给addEventListener / removeEventListener。当你传递this.updateValue.bind(this)时,你实际上是在创建一个新函数,因此这两个函数是不一样的。
相反,将updateValue转换为箭头表示法,将this
保持为类的this
,然后您可以两次发送对同一函数的引用。
答案 1 :(得分:3)
我认为你需要在构造函数中只绑定一次函数。 因为.bind()返回一个新的函数对象,所以removeEventListener不会删除你所做的初始事件监听器函数。