You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

额外优化点

  1. 删除了无用的keyCode状态;
  2. 调整handleSubmit里状态更新顺序,先清空错误信息再导航,逻辑更合理;
  3. 移除全局keydown事件监听,仅在输入框上监听Enter,避免全局事件带来的意外触发。

内容的提问来源于stack exchange,提问作者Misbahu Abubakar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:05:30