Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

176
Views
Why does render triggered only once every two keydowns?

Problem :

Goal : Each time I press on keys "W+C+N", an image appears randomly on my screen.

Actual result : The image appears only every two keydowns. For example, if I press 4 times on "W+C+N", only 2 new images appear.

What I've tried / guessing where the problem stems from :

Misuse of my useEffect, it either comes from :

  • a miscomprehension of the removeEventListener method, does it "disables" my setcoordinates inside of my handleKey function?
  • not specifying the right dependency [handleKey] : handleKey function is activated by keypress and changes on new coordinates. So it seems correct to re-render each time i pass a new coordinate
  • VS Code warning : "the 'handleKey" function makes the dependencies of useState Hook change on every render. Move it inside the useEffect callback." I did try that but it doesn't work anymore then.

My actual code

import egg from "./logo.png";
import { useState, useEffect } from "react";

function App() {
  let map = []; //array of keys to store
  const [coordinates, setcoordinates] = useState([]); //array of image coordinates

  const handleKey = (event) => {
    onkeydown = onkeyup = function (event) {
      map[event.keyCode] = event.type === "keydown";
    };
    //random image coordinates
    if (map[87] && map[67] && map[78]) {
      const newCoordinates = [...coordinates];
      let random_left = Math.floor(Math.random() * window.innerWidth);
      let random_top = Math.floor(Math.random() * window.innerHeight);
      newCoordinates.push({ left: random_left, top: random_top });
      setcoordinates(newCoordinates);
    }
  };
  useEffect(() => {
    window.addEventListener("keypress", handleKey);
    return () => {
      window.removeEventListener("keypress", handleKey);
    };
  }, [handleKey]);
  return (
    <div className="App">
      <img src={egg} alt="o easter egg" />
      <h1>Rocambole</h1>
      <h2>Good luck!</h2>
      {console.log(coordinates)}
      {coordinates.map((item, index) => {
        return (
          <img
            key={index}
            src={egg}
            alt="egg"
            className="newImg"
            style={{ top: `${item.top}px`, left: `${item.left}px` }}
          />
        );
      })}
    </div>
  );
}

export default App;

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Try updating the state with a function, this way you ensure that the event listener registred in memory gets the fresh state every time, and also move the function handleKey inside useEffect:

import egg from "./logo.png";
import { useState, useEffect } from "react";

function App() {
  let map = []; //array of keys to store
  const [coordinates, setcoordinates] = useState([]); //array of image coordinates
  useEffect(() => {
    const handleKey = (event) => {
      onkeydown = onkeyup = function (event) {
        map[event.keyCode] = event.type === "keydown";
      };
      //random image coordinates
      if (map[87] && map[67] && map[78]) {
        let random_left = Math.floor(Math.random() * window.innerWidth);
        let random_top = Math.floor(Math.random() * window.innerHeight);
   
        setcoordinates(coordinates =>[...coordinates, { left: random_left, top: random_top }]);
      }
    };
    window.addEventListener("keypress", handleKey);
    return () => {
      window.removeEventListener("keypress", handleKey);
    };
  }, []);
  return (
    <div className="App">
      <img src={egg} alt="o easter egg" />
      <h1>Rocambole</h1>
      <h2>Good luck!</h2>
      {console.log(coordinates)}
      {coordinates.map((item, index) => {
        return (
          <img
            key={index}
            src={egg}
            alt="egg"
            className="newImg"
            style={{ top: `${item.top}px`, left: `${item.left}px` }}
          />
        );
      })}
    </div>
  );
}

export default App;
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!