首页 > 解决方案 > React removeEventListener 没有被移除

问题描述

我已经浏览了很多谷歌搜索,但仍然无法解决这个问题。

我有一个我希望能够通过按键选择的按钮列表。按“A”时,您会选择“A: Xxxxxxxx” select。当按下 B 时,您会选择“B: yyyyyyyy” select

  const d = useDispatch();
  const s = useSelector(select);
  const [selected, setSelected] = useState(s);

  const eventHandler = function (card, i, setSelected, d, set) {
    return e => {
      if (alphabet.indexOf(e.key) === i) {
        setSelected(card.key);
        d(set(card.key));
      }
    };
  };

  useEffect(() => {
    cards.map((card, i) => {
      window.addEventListener(
        "keypress",
        eventHandler(card, i, setSelected, d, set),
        false
      );
    });
    return () => {
      window.removeEventListener("keypress", eventHandler, false);
    };
  }, []);

现在,我发现,您需要为它们指定函数引用才能工作,但我不知道如何将这些变量传递到处理按钮按下cards.map的函数中?eventHandler我真的迷路了……

标签: javascriptreactjs

解决方案


您正在向窗口添加一堆事件侦听器。您需要将事件存储到某些东西中并引用它们以删除它们。

const myEvents = []
const eventHandler = function (card, i, setSelected, d, set) {
  const fnc = e => {
    if (alphabet.indexOf(e.key) === i) {
      setSelected(card.key);
      d(set(card.key));
    }
  };
  myEvents = fnc
  return fnc
};

useEffect(() => {
  cards.map((card, i) => {
    window.addEventListener(
      "keypress",
      eventHandler(card, i, setSelected, d, set),
      false
    );
  });
  return () => {
    myEvents.forEach(evt => 
      window.removeEventListener("keypress", evt, false))
  };
}, []);

最后这段代码效率很低。您应该绑定一个事件处理程序并查看密钥是否与任何卡匹配。

基本想法是

const lookUpCard = e => {
  const index = alphabet.indexOf(e.key)
  const myCard = cards[index]
})

window.addEventListener("keypress", lookUpCard)

推荐阅读