Reputation: 15
import React from "react";
import { useState } from "react";
import { useEffect } from "react";
export default function Plane() {
const [left, setLeft] = useState();
useEffect(() => {
setLeft(50);
}, []);
document.addEventListener("keydown", function (e) {
switch (e.keyCode) {
case 37:
return setLeft(left - 1);
case 39:
return setLeft(left + 1);
case 38:
return console.log("up");
case 40:
return console.log("down");
}
});
console.log('plane')
return <div className="playerControl" style={{ left: `${left}%` }}></div>;
}
basically, I want to do left-right the plane it's working but causing an issue when I press the key console. log('plane') logging plane multiple time 1st press 2 times total console.log= 2...........2nd press 4 times total console.log = 6...........3rd press 8 times total console.log = 14...........4th press 16 times total console.log = 30...........enter image description here5th press 32 times total console.log = 62.
Upvotes: 1
Views: 64
Reputation: 1812
import React from "react";
import { useState } from "react";
import { useEffect } from "react";
export default function Plane() {
const [left, setLeft] = useState(50);
useEffect(() => {
// Extract function into standalone
// Event listener needs same reference in
// .addEventListener and .removeEventListener to cleanup properly
const handleKeyDown = e => {
switch (e.keyCode) {
case 37:
return setLeft(prev => prev - 1);
case 39:
return setLeft(prev => prev + 1);
case 38:
return console.log("up");
case 40:
return console.log("down");
}
}
// Set event listener once when the component mounts
document.addEventListener("keydown", handleKeyDown);
// Clean up listener when component unmounts
return () => {
document.removeEventListener("keydown", handleKeyDown);
}
}, []);
console.log('plane')
return <div className="playerControl" style={{ left: `${left}%` }}></div>;
}
Upvotes: 1
Reputation: 161
James is right, event listeners should be defined inside effect hook, moreover you should also unsubscribe from them in the hook return function like so
useEffect(() => {
document.addEventListener('keydown', callback);
return () => {
document.removeEventListener('keydown', callback);
}
}
Upvotes: 4