最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - removeEventListener not working when called in componentWillUnmount - Stack Overflow

programmeradmin0浏览0评论

I'm trying to setState() such that it renders different number of items on different screen sizes set to component state as the window is resized. I've added an event listener when the component mounts and removed it when it unmounts.

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));
}

Works fine when I'm in the route with the component mounted; until I move away from the component by opening another route and resize the window which is when I get the error:

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 FeaturedRestaurants component.

I get like a hundred errors in a second as I resize the screen.

Clearly, the removeEventListener isn't working. Where did I go wrong?

I'm trying to setState() such that it renders different number of items on different screen sizes set to component state as the window is resized. I've added an event listener when the component mounts and removed it when it unmounts.

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));
}

Works fine when I'm in the route with the component mounted; until I move away from the component by opening another route and resize the window which is when I get the error:

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 FeaturedRestaurants component.

I get like a hundred errors in a second as I resize the screen.

Clearly, the removeEventListener isn't working. Where did I go wrong?

Share Improve this question edited May 1, 2020 at 9:18 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Nov 20, 2017 at 7:31 anonymanonym 4,85012 gold badges49 silver badges76 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 13

Try doing the following:

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);
}

You have to pass the same function as the second parameter to the addEventListener/removeEventListener. When you pass this.updateValue.bind(this), you are actually creating a new function and as such the two functions aren't the same. Instead, convert updateValue to arrow notation, keeping this as this of the class, and then you can send a reference to the same function twice.

I think you need to bind the function only once in the constructor. Because .bind() returns a new function object, removeEventListener will not remove initial event listener function you made.

发布评论

评论列表(0)

  1. 暂无评论