React登录页面Enter键keydown事件失效问题求助
问题原因
核心问题是闭包导致keydown事件处理函数捕获了旧的input状态:
- 绑定在
document.body上的keydown事件仅在组件首次渲染时注册,此时keyDown函数捕获的input是初始空值; - 后续输入框内容更新时,
keyDown函数依然保留着首次渲染时的input引用,按下Enter时发送的login参数为空字符串,后端因此返回“用户未找到”错误; - 而
handleSubmit是组件每次渲染都会重新定义的函数,能实时拿到最新的input状态,所以点击按钮时请求正常。
最优解决方案
直接在输入框上绑定onKeyDown事件,复用已有的handleSubmit逻辑,既避免闭包问题,又减少代码重复:
修改后的代码
import Axios from "axios"; import { useState, useRef, useEffect } from "react"; import { useNavigate } from "react-router-dom"; const LogIn = () => { const milliseconds = 3600000; localStorage.setItem("twoHours", JSON.stringify(milliseconds)); const userRef = useRef(); const navigate = useNavigate(); const [input, setInput] = useState(""); const [errorMessage, setErrorMessage] = useState(""); const [error, setError] = useState(false); useEffect(() => { userRef.current.focus(); }, []); const handleSubmit = async () => { try { const data = await Axios.post("http://localhost:3500/examAuth", { login: input, }); setError(false); setErrorMessage(""); navigate("/examSection", { state: { user: data.data } }); } catch (error: any) { setError(true); setErrorMessage(error.response.data.message); console.log(error); } }; return ( <> <div className=""> <div className="w-1/6 mx-auto mt-10"> <img src="images/editedConst.png" alt="" /> </div> <div className="flex flex-col gap-2 w-3/4 mx-auto mt-10"> <label className="text-yellow-700 text-xl w-2/4 mx-auto" htmlFor="logIn" > Login </label> <input ref={userRef} className="input w-2/4 mx-auto" autoComplete="off" autoSave="off" type="text" value={input} name="login" placeholder="application number" onChange={(e) => setInput(e.target.value.trim().toUpperCase())} // 新增:绑定输入框的Enter事件,直接调用handleSubmit onKeyDown={(e) => { if (e.code === "Enter") { handleSubmit(); } }} required /> {error && ( <p className="mt-1 mx-auto w-2/4 text-red-500">{errorMessage}</p> )} </div> <div className="flex justify-center w-2/4 mx-auto mt-8"> <button className="btn shadow shadow-yellow-800" onClick={handleSubmit} > Log In </button> </div> </div> </> ); }; export default LogIn;
额外优化点
- 删除了无用的
keyCode状态; - 调整
handleSubmit里状态更新顺序,先清空错误信息再导航,逻辑更合理; - 移除全局
keydown事件监听,仅在输入框上监听Enter,避免全局事件带来的意外触发。
内容的提问来源于stack exchange,提问作者Misbahu Abubakar
相关产品推荐
相关产品推荐

