TransWikia.com

Why is the console.log() printing multiple times with all the previous values?

Stack Overflow Asked by Itay Zuker on January 29, 2021

When I click the plus button, the number state updates with +1 as expected.
But if I click the plus button 5 times (Or any other number of times).
when I try to print the number value in the console with the keydown event, I get five prints of 0 to 5
(Or as many times as I previously clicked the plus button). Why is this happening? And how can I get just one print with the current (updated) value?

This is the screenshot

let [number, setNumber] = useState(0)

function plus() {setNumber(number += 1)}

function ptintNumber() {
    console.log(number)
}

document.addEventListener('keydown', ptintNumber)

return <div>
    <h1>{number}</h1>
    <button onClick={plus}>+</button>
</div>   

3 Answers

If you wish to see the value, you need to use a useEffect hook that will react to the number change. The value you could be outputting with your method might not be the right value

import React, { useEffect, useState } from "react";

export default function App() {
  let [number, setNumber] = useState(0);
  function plus() {
    setNumber((previousNumber) => previousNumber + 1);
  }

  useEffect(() => {
    console.log(number);
  }, [number]);

  return (
    <div className="App">
      <h1>{number}</h1>
      <button onClick={plus}>+</button>
    </div>
  );
}

You should also base your new value on the previous one

Codesandbox example

Answered by Victor Jozwicki on January 29, 2021

To answer your specific question: the reason this happens is because you tie an event listened to your document on every render, which happens each time you click the Plus button. So every keydown is calling your ptintNumber exactly as many time as you clicked the Plus button.

Solution: Put your even listener into useEffect like so:

import React from "react";
import "./styles.css";

export default function App() {
  let [number, setNumber] = React.useState(0);
  const number_ref = React.useRef();
  number_ref.current = number;

  function plus() {
    setNumber((number += 1));
  }

  function ptintNumber() {
    console.log(number_ref.current);
  }

  React.useEffect(() => {
    document.addEventListener("keydown", ptintNumber);
  }, []);

  return (
    <div className="App">
      <h1>{number}</h1>
      <button onClick={plus}>+</button>
    </div>
  );
}

Sandbox: https://codesandbox.io/s/wizardly-antonelli-vix6q?file=/src/App.js

Answered by codemonkey on January 29, 2021

You can use onKeyDown instead of addEventListener

function ButtonComp() {
    let [number, setNumber] = useState(0);
    // document.addEventListener("keydown", ptintNumber);

    return (
        <div>
            <h1>{number}</h1>
            <button onClick={() => setNumber(number+1)} onKeyDown={() => {console.log(number)}}>+</button>
        </div>
    );
}

Answered by Hemant Malik on January 29, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP