I have this small project in Codesandbox using React
What I was trying to make this ship move around the screen using arrow keys
I have a function that detects when an key is pressed, then checks if this key is an arrow key, and if so, I change the coordinates of the image so the image can move around the screen
This is the code
import { useState } from "react";
import { constants } from "../../constants";
import "./space-ship.styles.css";
export const Spaceship = (): JSX.Element => {
const [horizontalCords, setHorizontalCords] = useState<number>(0);
const [verticalCords, setVerticalCords] = useState<number>(0);
const validateArrowKey = (key: KeyboardEvent): void => {
console.log("called one");
if (key.keyCode === 37) {
setHorizontalCords(horizontalCords - 10);
return;
}
//left
else if (key.keyCode === 39)
return setHorizontalCords(horizontalCords + 10);
//right
else if (key.keyCode === 38) return setVerticalCords(verticalCords - 10);
//up
else if (key.keyCode === 40) return setVerticalCords(verticalCords + 10);
// down;
};
window.addEventListener("keydown", validateArrowKey);
return (
<img
style={{
left: horizontalCords + "px",
top: verticalCords + "px"
}}
className="space-ship"
src={constants.space_ship}
alt="Space ship"
/>
);
};
I have a console log at the beggining of the function,and when I press the arrow key about 10 times this happens:
console log being called over 3000 times
And if I continue to press the keys the app crashes
Can anyone help me to stop the function being called a million times?
I tried to searching about re-renders in React and how state changes, I’ve tried using useCallbacks and changing the useEffect but nothing worked
2
Answers
It is because
window.addEventListener
called every time when re-render (caused bysetHorizontalCords
), so the same listener keeping add more and more and never cleanup, you can useuseEffect
to handle the event of add/remove listenerdid you try cleaning up the event listener on the useEffect?
I was able to reduce the rendering with this.