偶遇this之坑
事件:在使用reactJS时候,写了一个上拉加载的方法。但在当前页面不进行上拉,跳转至其他页面后在回退回来进行上拉加载,就会出现问题warning警告,如下:
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 ActivityComponent component.
方法实现:
根据滚动条高度加屏幕高度来判断是否加载:
componentDidMount(){
window.addEventListener("scroll", this.handleScroll);
}
componentWillUnmount(){
window.removeEventListener("scroll", this.handleScroll);
}
handleScroll方法如下:
handleScroll(){
var _this=this;
if(!_this.state.maxPage){
if(_this.state.loading){
util.scroll.hitBottom(function(){
_this.setState({'loading': false});
var options={
page:_this.state.page,
rows:_this.state.rows
}
Actions.getNoticeList(options);
})
}
}else{
window.removeEventListener("scroll",_this.handleScroll);
}
}
这个代码已经解决了this的指向问题,也就是下面这句:
window.addEventListener("scroll", this.handleScroll.bind(this));
但这样的问题是,bind返回的是一个新对象,而不是原本的this.handleScroll。一般情况下,这也不是什么大问题,但坑就坑在this.handleScroll里面的这句:
var _this=this;
看似一切都正常,但这是一个大坑,this.handScroll.bind(this)这是一个新对象,因此你根本就无法remove掉这个新对象。所以最终才想出个迫不得已的方法就是让this.handScroll变成新的那个对象。
即:
componentDidMount(){
this.handleScroll = this.handleScroll.bind(this);
window.addEventListener("scroll", this.handleScroll);
}
componentWillUnmount(){
window.removeEventListener("scroll", this.handleScroll);
}
附录:util.scroll方法
export const scroll = {
getScrollTop:function(){
var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
if(document.body){
bodyScrollTop = document.body.scrollTop;
}
if(document.documentElement){
documentScrollTop = document.documentElement.scrollTop;
}
scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
return scrollTop;
},
//文档的总高度
getScrollHeight:function(){
var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
if(document.body){
bodyScrollHeight = document.body.scrollHeight;
}
if(document.documentElement){
documentScrollHeight = document.documentElement.scrollHeight;
}
scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
return scrollHeight;
},
//浏览器视口的高度
getWindowHeight:function(){
var windowHeight = 0;
if(document.compatMode == "CSS1Compat"){
windowHeight = document.documentElement.clientHeight;
}else{
windowHeight = document.body.clientHeight;
}
return windowHeight;
},
hitBottom:function(callback,height=0){
if(this.getScrollHeight()-(this.getScrollTop() + this.getWindowHeight()) <= height ){
callback && callback();
}
}
}