React Hooks removeEventListener 使用无效问题

组件卸载时

和原来的componentWillUnmount一样的用法, 在useEffect return里调用就可以了

 useEffect(() => {
    window.addEventListener('click', clickFunc);
    return () => {
      window.removeEventListener('click', clickFunc);
    };
  });

组件使用过程中

当组件不涉及重新渲染时了, 像这么写完全没问题, 点击Remove Click to Console之后监听取消.

import React, { useState } from "react";

  const App = () => {
    // const [state, setState] = useState(0)

    const handleAddListening = () => {
      window.addEventListener('click', clickFunc)
      // setState(state + 1)
    }

    const clickFunc = () => {
      console.log('clicking')
    }

    const handleRemoveListening = () => {
      window.removeEventListener('click', clickFunc)
    }

    return (
      <div className="App">
        <div onClick={handleAddListening}>
          Click to Console
        </div>
        <div onClick={handleRemoveListening}>
          Remove Click to Console
        </div>
      </div>
  );
}

现在我们把以上代码中的注释取消掉, 加入useState导致组件再次渲染, 此时发现无论如何点击Remove Click to Console, 点击事件发生时, 会一直console clicking.
甚至再次单击Click to Console触发绑定事件, 发现会同时console clicking两次;
再再次单击, console次数会继续累计增加.

这是因为每次触发组件再次渲染, clickFunc作为组件内的方法, 会跟着一同再次渲染, 并且在内存里, 再次渲染出的 clickFunc !== 前clickFunc.
所以removeEventListener无法解除绑定, 再次addEventListener则会绑定一个新方法.

解决方案:

const clickFunc = useCallback(() => {
    console.log("clicking");
  }, []);

使用无依赖的useCallback解决clickFunc的重新渲染问题

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值