简体   繁体   English

React removeEventListener 没有被移除

[英]React removeEventListener not being removed

I have already looked through a lot of Googling, but still can't manage to fix this issue.我已经浏览了很多谷歌搜索,但仍然无法解决这个问题。

I've got a list of buttons that I want to be able to be selected by keypresses.我有一个我希望能够通过按键选择的按钮列表。 When pressing "A", you get "A: Xxxxxxxx" select selected.按“A”时,您会选择“A: Xxxxxxxx” select When pressed B, you get "B: yyyyyyyy" select selected.按下 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);
    };
  }, []);

Now, i found out, that you need to specify function references for them in order to work, but I can't get my head around how would I pass these variables from cards.map into the function eventHandler that handles the button presses?现在,我发现,您需要为它们指定 function 引用才能工作,但我不知道如何将这些变量从卡中传递cards.map到处理按钮的eventHandler中? I'm really lost here...我真的迷路了……

You are adding a bunch of event listeners to the window.您正在向 window 添加一堆事件侦听器。 You need to store the events into something and reference them to remove them.您需要将事件存储到某些东西中并引用它们以删除它们。

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))
  };
}, []);

In the end this code is really inefficient.最后这段代码效率很低。 You should be binding one event handler and looking up to see if the key matches any of the cards.您应该绑定一个事件处理程序并查看密钥是否与任何卡匹配。

Basic idea would be基本想法是

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

window.addEventListener("keypress", lookUpCard)

In the end I came up with something similar.最后我想出了类似的东西。 Accepting @epascarello's answer as accepted because he gave me the basic idea.接受@epascarello 的回答,因为他给了我基本的想法。

  export const alphabet = ["a", "b", "c", "d", "e", "f", "g", "h"];

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

  const keyPressHandler = (event) => {
    const index = alphabet.indexOf(event.key);
    if (index >= 0) {
      setSelected(cards[index].key);
      d(set(cards[index].key));
    }
  };

  useEffect(() => {
    window.addEventListener("keypress", keyPressHandler, false);
    return () => {
      window.removeEventListener("keypress", keyPressHandler, false);
    };
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM