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

React.js开发登录页输入内容时报Cannot read property 'length'错误

React登录页输入时报错排查

错误核心原因

  • useState更新对象时未合并原有状态
    你的handleChange函数直接用新对象覆盖了整个loginData状态:
// 错误写法,会丢失旧状态里的其他字段
setLoginData({[e.target.name]: e.target.value});

React的函数组件useState更新对象不会自动合并旧属性,当你输入邮箱/密码时,更新后的loginData就只剩当前修改的email或password字段,原本的errors字段会被直接移除,所以执行loginData.errors.length时errors是undefined,自然抛出找不到length属性的错误。
修正方式:更新状态时先解构原有旧状态,再覆盖新字段:

const handleChange = (e) => {
  setLoginData({
    ...loginData,
    [e.target.name]: e.target.value
  });
}
  • displayErrors函数无返回值
    你写的displayErrors里执行了map但没有return结果,即使有错误也不会渲染提示,修正:
const displayErrors = (errors) => {
  return errors.map((error,i)=> <p key={i}>{error}</p>)
}
  • 其他潜在错误
    1. 函数组件不存在this,你在submitForm里写的this.props.dispatch会报错,需要先给组件接收props参数:function RegisterLogin(props) {,然后改成props.dispatch
    2. 表单提交事件onSubmit应该绑定在<form>标签上,不是绑定在提交按钮上,现在的写法点击登录按钮不会触发提交逻辑
    3. submitForm里的setLoginData({errors: []})同样是全量覆盖状态,要改成setLoginData({...loginData, errors: []})

修正后的完整代码

import React,{useState} from "react";
import {connect} from "react-redux";
import {loginUser} from '../../actions/user_action'
// 接收props参数
function RegisterLogin(props) {
  const [loginData, setLoginData] = useState({
    email: "",
    password: "",
    errors: [],
  });

  const displayErrors = (errors) => {
    // 增加return返回渲染内容
    return errors.map((error,i)=> <p key={i}>{error}</p>)
  }

  const handleChange = (e) => {
    // 更新时合并旧状态,避免丢失其他字段
    setLoginData({
      ...loginData,
      [e.target.name]: e.target.value
    });
  }

  const submitForm = (e) => {
    e.preventDefault();
    let dataToSubmit ={
      email: loginData.email,
      password: loginData.password
    }
    if (isFormValid(loginData)){
      // 合并旧状态
      setLoginData({...loginData, errors: []});
      // 去掉this,直接用props调用dispatch
      props.dispatch(loginUser(dataToSubmit))
      .then(response => {console.log(response)})
    }
  }

  const isFormValid = ({email,password}) => email&&password;

  return (
    <div className="login-container">
      <div className="row login-box">
      <h2 className="login">登录</h2>
        {/* onSubmit绑定到form标签上才会生效 */}
        <form className="column s12" onSubmit={submitForm}>
          <div className="col">
            <div className="input-field col s12"> 
            {/* 邮箱输入框 */}
            <input
              name="email"
              value={loginData.email}
              onChange={handleChange}
              id="email"
              type="email"
              className="validate"
              placeholder="邮箱"
            />
            <span 
            className="helper-text"
            data-error="请输入合法邮箱"
            data-success="邮箱格式正确"
            />
            </div>
             {/* 密码输入框 */}
            <div className="input-field  col s12"> 
            <input
              name="password"
              value={loginData.password}
              onChange={handleChange}
              id="password"
              type="password"
              className="validate"
              placeholder="密码"
              autoComplete="off"
            />
            <span 
            className="helper-text"
            data-error="密码错误"
            data-success="正确"
            />
            </div>
          </div>
          {/* 错误提示渲染 */}
           {loginData.errors.length >0 &&(
            <div>
              {displayErrors(loginData.errors)}
            </div>
          )} 
         {/* 提交按钮 */}
          <div >
            <div className="col s12">
              <button 
              className="btn waves-white black brighten-2"
              type="submit"
              name="action"
              >
                登录
              </button>
              </div>
          </div>
        </form>
      </div>
      <div className="whatever">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
    </div>
  );
}

const mapStateToProps = (state) => {
  return {
    user: state.user
  }
}

export default connect(mapStateToProps)(RegisterLogin);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:45:05