React如何移除事件监听?

问题描述

1、在组件加载时,利用生命周期componentDidMount中添加事件监听。但在组件卸载时,在componentWillUnmount中无法移除事件
2、而在Angular框架中,就是采用在组件卸载时移除事件就可以成功,而在React中此思路完全失效,为什么会有这种差异?

React版本信息

clipboard.png

相关代码

class Product extends Component {
    constructor() {
        super();
    }
    // 组件加载时
    componentDidMount() {
        this.scrollEvent();
    }
    // 组件卸载时
    componentWillUnmount() {
        window.removeEventListener("scroll", this.onScroll.bind(this));
    }
    // 添加事件监听
    scrollEvent() {
        window.addEventListener("scroll", this.onScroll.bind(this));
    }
    // 事件监听方法
    onScroll() {
        console.log("滚动条正在滚动");
    }
}


你期待的结果是什么?实际看到的错误信息又是什么?

1、期望结果是:在组件完成卸载时,移除事件监听,onScroll方法停止执行输出"滚动条正在滚动"字符串
2、实际结果是:当前组件已经卸载,已经进入到另一个组件时,onScroll方法仍然在执行输出"滚动条正在滚动"字符串

阅读 9.8k
2 个回答

bind()会创建一个新的函数,所以示例中添加和解除绑定的不是同一个函数:

function a () {}
a === a  // true
a.bind(this) === a.bind(this)  // false

在 constructor 中绑定 this:

class Product extends Component {
    constructor() {
        super();
        this.onScroll = this.onScroll.bind(this)
    }
    // 组件加载时
    componentDidMount() {
        this.scrollEvent();
    }
    // 组件卸载时
    componentWillUnmount() {
        window.removeEventListener("scroll", this.onScroll);
    }
    // 添加事件监听
    scrollEvent() {
        window.addEventListener("scroll", this.onScroll);
    }
    // 事件监听方法
    onScroll() {
        console.log("滚动条正在滚动");
    }
}

jsbind的用法是给函数绑定一个上下文,然后返回一个新函数,你这里addEventListenerremoveEventListener用的是bind的返回值,监听和移除的不是同一个对象,建议把bind代码放进constructor里。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题