简体   繁体   English

removeEventListener 似乎不起作用。 addEventListener 回调在每次渲染时触发的次数越来越多

[英]removeEventListener seems not working. addEventListener callback fires more and more times with every render

I know there are many questions about removeEventListener on stackoverflow, but none of the answers have worked for me.我知道在 stackoverflow 上有很多关于 removeEventListener 的问题,但没有一个答案对我有用。

I am also not sure if removeEventListener is the issue causing problem.我也不确定 removeEventListener 是否是导致问题的问题。

i wrote 2048 game clone, but with every arrow click eventListener fires 2 times more than previously (2,4,8,16...) so after around 10 clicks app stops working.我写了 2048 游戏克隆,但每次单击箭头时,事件监听器都会比以前多触发 2 倍(2、4、8、16 ...),因此在大约 10 次点击后,应用程序停止工作。

I spent hours trying to find the issue but cannot find it...我花了几个小时试图找到问题,但找不到它......

The entire app code is below, its written in react:整个应用程序代码如下,它是用 React 编写的:

    import "./Board.css"
    import {useEffect, useState} from "react";
    import {v4} from "uuid"

    const Board = () => {
        const [globalBoard, setGlobalBoard] = useState(null)
    useEffect(()=>{
     initializeGame()
    },[])

    useEffect(()=>{
        const handleGame = (e, board) => {


            if (e.key !== "ArrowUp" &&
                e.key !== "ArrowDown" &&
                e.key !== "ArrowLeft" &&
                e.key !== "ArrowRight"
            ) return


            if (e.key === "ArrowUp") {

                //take all numbers up
                for (let i = 0; i < 3; i++) {
                    for (let j = 0; j < 4; j++) {

                        let k = 0
                        while (board[i][j] === 0 && k < 3) {
                            if (i === 0) {
                                board[i][j] = board[i + 1][j]
                                board[i + 1][j] = board[i + 2][j]
                                board[i + 2][j] = board[i + 3][j]
                                board[i + 3][j] = 0
                            }
                            if (i === 1) {
                                board[i][j] = board[i + 1][j]
                                board[i + 1][j] = board[i + 2][j]
                                board[i + 2][j] = 0
                            }

                            if (i === 2) {
                                board[i][j] = board[i + 1][j]
                                board[i + 1][j] = 0
                            }
                            k++
                        }
                    }
                }
                //summarize all numbers
                for (let i = 0; i < 3; i++) {
                    for (let j = 0; j < 4; j++) {


                        if (board[i][j] !== 0 && board[i][j] === board[i + 1][j]) {
                            board[i][j] *= 2


                            if (i === 0) {
                                board[i + 1][j] = board[i + 2][j]
                                board[i + 2][j] = board[i + 3][j]
                                board[i + 3][j] = 0
                            }

                            if (i === 1) {
                                board[i + 1][j] = board[i + 2][j]
                                board[i + 2][j] = 0
                            }

                            if (i === 2) {
                                board[i + 1][j] = 0
                            }
                        }

                    }
                }
            }

            if (e.key === "ArrowDown") {


                //take all numbers down
                for (let i = 3; i > 0; i--) {
                    for (let j = 0; j < 4; j++) {

                        let k = 0
                        while (board[i][j] === 0 && k < 3) {
                            if (i === 3) {
                                board[i][j] = board[i - 1][j]
                                board[i - 1][j] = board[i - 2][j]
                                board[i - 2][j] = board[i - 3][j]
                                board[i - 3][j] = 0
                            }
                            if (i === 2) {
                                board[i][j] = board[i - 1][j]
                                board[i - 1][j] = board[i - 2][j]
                                board[i - 2][j] = 0
                            }

                            if (i === 1) {
                                board[i][j] = board[i - 1][j]
                                board[i - 1][j] = 0
                            }
                            k++
                        }
                    }
                }
                //summarize all numbers
                for (let i = 3; i > 0; i--) {
                    for (let j = 0; j < 4; j++) {


                        if (board[i][j] !== 0 && board[i][j] === board[i - 1][j]) {
                            board[i][j] *= 2


                            if (i === 3) {
                                board[i - 1][j] = board[i - 2][j]
                                board[i - 2][j] = board[i - 3][j]
                                board[i - 3][j] = 0
                            }

                            if (i === 2) {
                                board[i - 1][j] = board[i - 2][j]
                                board[i - 2][j] = 0
                            }

                            if (i === 1) {
                                board[i - 1][j] = 0
                            }
                        }
                    }
                }
            }

            if (e.key === "ArrowLeft") {


                //take all numbers to the left
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 3; j++) {

                        let k = 0
                        while (board[i][j] === 0 && k < 3) {
                            if (j === 0) {
                                board[i][j] = board[i][j + 1]
                                board[i][j + 1] = board[i][j + 2]
                                board[i][j + 2] = board[i][j + 3]
                                board[i][j + 3] = 0
                            }
                            if (j === 1) {
                                board[i][j] = board[i][j + 1]
                                board[i][j + 1] = board[i][j + 2]
                                board[i][j + 2] = 0
                            }

                            if (j === 2) {
                                board[i][j] = board[i][j + 1]
                                board[i][j + 1] = 0
                            }
                            k++
                        }
                    }
                }
                //summarize all numbers
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 3; j++) {


                        if (board[i][j] !== 0 && board[i][j] === board[i][j + 1]) {
                            board[i][j] *= 2


                            if (j === 0) {
                                board[i][j + 1] = board[i][j + 2]
                                board[i][j + 2] = board[i][j + 3]
                                board[i][j + 3] = 0
                            }

                            if (j === 1) {
                                board[i][j + 1] = board[i][j + 2]
                                board[i][j + 2] = 0
                            }

                            if (j === 2) {
                                board[i][j + 1] = 0
                            }
                        }
                    }
                }
            }

            if (e.key === "ArrowRight") {


                //take all numbers to the left
                for (let i = 0; i < 4; i++) {
                    for (let j = 3; j > 0; j--) {

                        let k = 0
                        while (board[i][j] === 0 && k < 3) {
                            if (j === 3) {
                                board[i][j] = board[i][j - 1]
                                board[i][j - 1] = board[i][j - 2]
                                board[i][j - 2] = board[i][j - 3]
                                board[i][j - 3] = 0
                            }
                            if (j === 2) {
                                board[i][j] = board[i][j - 1]
                                board[i][j - 1] = board[i][j - 2]
                                board[i][j - 2] = 0
                            }

                            if (j === 1) {
                                board[i][j] = board[i][j - 1]
                                board[i][j - 1] = 0
                            }
                            k++
                        }
                    }
                }
                //summarize all numbers
                for (let i = 0; i < 4; i++) {
                    for (let j = 3; j > 0; j--) {

                        if (board[i][j] !== 0 && board[i][j] === board[i][j - 1]) {
                            board[i][j] *= 2

                            if (j === 3) {

                                board[i][j - 1] = board[i][j - 2]
                                board[i][j - 2] = board[i][j - 3]
                                board[i][j - 3] = 0
                            }

                            if (j === 2) {
                                board[i][j] = board[i][j - 1]
                                board[i][j - 1] = board[i][j - 2]
                                board[i][j - 2] = 0
                            }

                            if (j === 1) {
                                board[i][j] = board[i][j - 1]
                                board[i][j - 1] = 0
                            }
                        }
                    }
                }
            }


//check if previous board differs from the current one (if it does not, we don't want to add extra number)


            console.log(globalBoard)
            let arrayChanged = false
            for (let i = 0; i < 4; i++) {
                for (let j = 0; j < 4; j++) {
                    if (globalBoard[i][j] !== board[i][j]){


                        arrayChanged = true
                    }
                }
            }

            if (arrayChanged){
                //draw a spot on the board
                let number1 = Math.floor(Math.random() * 4)
                let number2 = Math.floor(Math.random() * 4)


                //check if the spot is empty - does not contain a number
                while (board[number1][number2] !==0){
                    number1 = Math.floor(Math.random() * 4)
                    number2 = Math.floor(Math.random() * 4)
                }

                //create a new number: 2 or 4 (with 80% chance that it will be 2) and place it in the selected spot
                board[number1][number2] = (Math.floor(Math.random() * 10) >= 8) ? 4 : 2;



                setGlobalBoard([...board])
            }
        }

        if (globalBoard){

            let board = [[...globalBoard[0]],[...globalBoard[1]],[...globalBoard[2]],[...globalBoard[3]]]
                window.addEventListener("keydown",(e)=> handleGame(e,board))

        }

        return ()=> window.removeEventListener("keydown",handleGame)

    },[globalBoard])

    const initializeGame = () => {
        let board = []
        for (let i = 0; i < 4; i++) {
            board.push([])
            for (let j = 0; j < 4; j++){
                board[i].push(0)
            }
        }

        let randomNr1 = Math.floor(Math.random()*4)
        let randomNr2 = Math.floor(Math.random()*4)

        //push first number
        board[randomNr1][randomNr2] = 2;
        let newRandomNr1;
        let newRandomNr2;

       do {
           newRandomNr1 = Math.floor(Math.random()*4)
           newRandomNr2 = Math.floor(Math.random()*4)

       }while (randomNr1===newRandomNr1 && randomNr2===newRandomNr2)

        board[newRandomNr1][newRandomNr2] = (Math.floor(Math.random()*10) >= 8) ? 4 : 2
        setGlobalBoard(board)

        return board
    }


    return (
        <div className="board">
            {globalBoard && globalBoard.map((array)=>{
              return array.map((el)=>{
                   return <div key={v4()} className="element">{el === 0 ? "" : el}</div>
               })
            })}
        </div>
    );
};


export default Board;

Change to this改成这样
To delete a listener, you need to pass the same function to it as to create a listner.要删除侦听器,您需要将与创建侦听器相同的 function 传递给它。 We create an intermediate function beginHandleGame and pass it to create a listner and delete it.我们创建一个中间 function beginHandleGame并将其传递给创建一个监听器并将其删除。

let board;
const beginHandleGame (e) => {
  handleGame(e,board);
}
if (globalBoard){

  board = [[...globalBoard[0]],[...globalBoard[1]],[...globalBoard[2]],[...globalBoard[3]]]
  
  window.addEventListener("keydown", beginHandleGame);

}

return ()=> window.removeEventListener("keydown", beginHandleGame)

You should pass the same handler to addEventListener and removeEventListener.您应该将相同的处理程序传递给 addEventListener 和 removeEventListener。

At first, you have created an event listener and passed the anonymous arrow function, after all, you remove that event and pass handlegame function.首先,您创建了一个事件侦听器并传递了匿名箭头 function,之后您删除了该事件并传递handlegame function。

Your code should look like this.您的代码应如下所示。

    const handler = (e) => {
       //do something
     }

window.addEventListener('keydown', handler)
//.....//
window.removeEventListener('keydown', handler)

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

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