Shubham Negi
Shubham Negi

Reputation: 15

react components rendering too much time

 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

Answers (2)

rantao
rantao

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

Sovari
Sovari

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

Related Questions