import { useState, useRef, useEffect } from "react";
function App() {
const [message, setMessage] = useState("");
const inpt = useRef();
const handleKeyDown = (e) => {
if (e.key === "Enter") {
handleClick();
}
};
useEffect(() => {
inpt.current.addEventListener("keydown", handleKeyDown);
return () => inpt.current.removeEventListener("keydown", handleKeyDown);
}, []);
function handleClick() {
console.error(message);
}
return (
<>
<div>
<input ref={inpt} type="text" name="" id="" value={message} onChange={(e)=> setMessage(e.target.value)} />
<button onClick={handleClick}>click</button>
</div>
</>
);
}
export default App;
When I click on the button I can log message
correctly, but when I press the "Enter" key message
logs as the initial value ""
.
Can you help me understand why this happening and what I should do?
2
Answers
Since you are using empty dependency array in
useEffect
hook, upon re-renders due to the state changes, its cleanup function wont get executed andref
will keep pointing to staleinput
element.To avoid this, you should add
message
ofhandleKeydown
as dependency.You need to make the
message
a dependency of the effect, as Ravi stated.Use a form
I better way to do this would to use a form. It has built-in Enter key support.
If you are using a ref on the field, you do not need to store a state!