Home > Mobile >  removeEventListener seems not working. addEventListener callback fires more and more times with ever
removeEventListener seems not working. addEventListener callback fires more and more times with ever

Time:10-03

I know there are many questions about removeEventListener on stackoverflow, but none of the answers have worked for me.

I am also not sure if removeEventListener is the issue causing problem.

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.

I spent hours trying to find the issue but cannot find it...

The entire app code is below, its written in 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;

CodePudding user response:

Change to this
To delete a listener, you need to pass the same function to it as to create a listner. We create an intermediate function beginHandleGame and pass it to create a listner and delete it.

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)

CodePudding user response:

You should pass the same handler to addEventListener and 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.

Your code should look like this.

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

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