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

React中users数组在handleSignUpSubmit函数外为空的问题求助

问题原因及解决方案

核心问题分析

  • 组件渲染重置数组:users数组定义在组件函数顶层,React每次渲染组件时都会重新创建这个空数组。哪怕你在注册时往数组里push了数据,组件重新渲染后数组会被重置为空,所以在handleSignUpSubmit外访问时,它始终是空的。
  • 对象引用导致匹配失效:用users.includes(loginUserDetails)永远返回false,因为includes比较的是对象引用——你创建的loginUserDetails是新对象,和users里的对象引用不同,哪怕内容完全一致也匹配不上。
  • 未从localStorage读取数据:登录逻辑里没有从localStorage取出已存储的用户列表,而是直接用组件里的空数组,自然无法匹配到注册过的用户。

修复后的完整代码

import { useRef, useState } from "react";
import styles from "../../styles/Login/Login.module.css";

interface User {
  username: string;
  password: string;
}

const Login = (): JSX.Element => {
  const signUpRef = useRef<HTMLInputElement>(null);
  const signUpPasswordRef = useRef<HTMLInputElement>(null);
  const loginRef = useRef<HTMLInputElement>(null);
  const loginPasswordRef = useRef<HTMLInputElement>(null);

  // 用state存储用户列表,初始化时从localStorage读取已有数据
  const [users, setUsers] = useState<User[]>(() => {
    const storedUsers = localStorage.getItem("user");
    return storedUsers ? JSON.parse(storedUsers) : [];
  });

  const handleSignUpSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    const userDetails: User = {
      username: signUpRef.current!.value,
      password: signUpPasswordRef.current!.value,
    };

    // 创建新数组更新state,同步到localStorage
    const updatedUsers = [...users, userDetails];
    setUsers(updatedUsers);
    localStorage.setItem("user", JSON.stringify(updatedUsers));

    signUpPasswordRef.current!.value = "";
    signUpRef.current!.value = "";
  };

  const handleLoginSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    const loginUserDetails: User = {
      username: loginRef.current!.value,
      password: loginPasswordRef.current!.value,
    };

    // 比较对象属性而非引用,判断用户是否存在
    const isUserExist = users.some(user => 
      user.username === loginUserDetails.username && user.password === loginUserDetails.password
    );

    isUserExist ? console.log("Welcome Back!") : console.log("Check your username or password again");

    loginRef.current!.value = "";
    loginPasswordRef.current!.value = "";
  };

  return (
    <>
      <form onSubmit={handleSignUpSubmit}>
        <h1>Sign Up</h1>
        <div>
          <label htmlFor="signup-username">Username</label>
          <input
            type="text"
            name="signup-username"
            className={styles.username}
            ref={signUpRef}
            id="signup-username"
            autoComplete="username"
          />
        </div>
        <div>
          <label htmlFor="signup-password">Password</label>
          <input
            type="password"
            name="signup-password"
            className={styles.password}
            ref={signUpPasswordRef}
            id="signup-password"
            autoComplete="new-password"
          />
        </div>
        <button type="submit">Sign Up</button>
      </form>

      <form onSubmit={handleLoginSubmit}>
        <h1>Login</h1>
        <div>
          <label htmlFor="login-username">Username</label>
          <input
            type="text"
            name="login-username"
            className={styles.username}
            id="login-username"
            ref={loginRef}
            autoComplete="username"
          />
        </div>
        <div>
          <label htmlFor="login-password">Password</label>
          <input
            type="password"
            name="login-password"
            className={styles.password}
            id="login-password"
            ref={loginPasswordRef}
            autoComplete="current-password"
          />
        </div>
        <button type="submit">Log In</button>
      </form>
    </>
  );
};

export default Login;

关键修复点说明

  • 用useState持久化用户数据:state会在组件渲染时保留数据,不会被重置,初始化时从localStorage读取已有用户,保证页面刷新后数据不丢失。
  • 更新数组时同步到localStorage:通过扩展运算符创建新数组,避免直接修改原state,同时把新数组存入localStorage。
  • 改用some方法匹配用户:直接比较username和password属性,替代依赖对象引用的includes方法。
  • 修正autoComplete属性:使用标准属性值,提升表单的自动填充体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:47:31