Reputation: 31
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?
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>
Upvotes: 1
Views: 5388
Reputation: 7915
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
Upvotes: 2
Reputation: 720
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
Upvotes: 1
Reputation: 1166
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>
);
}
Upvotes: 1