React登录页出现Uncaught TypeError错误,求修复方案
问题:React Hooks JWT认证登录页出现Uncaught TypeError错误
我正在学习React Hooks JWT认证,访问登录页面时出现Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))错误。以下是登录页代码:
import React, { useState, useRef } from "react"; import { useNavigate } from "react-router-dom"; import Form from "react-validation/build/form"; import Input from "react-validation/build/input"; import CheckButton from "react-validation/build/button"; import AuthService from "../service/auth.service"; const required = (value) => { if (!value) { return ( <div className="alert alert-danger" role="alert"> This field is required! </div> ); } }; const Login = () => { let navigate = useNavigate(); const form = useRef(); const checkBtn = useRef(); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [loading, setLoading] = useState(false); const [message, setMessage] = useState(""); const onChangeUsername = (e) => { const username = e.target.value; setUsername(username); }; const onChangePassword = (e) => { const password = e.target.value; setPassword(password); }; const handleLogin = (e) => { e.preventDefault(); setMessage(""); setLoading(true); form.current.validateAll(); if (checkBtn.current.context._errors.length === 0) { AuthService.login(username, password).then( () => { navigate("/profile"); window.location.reload(); }, (error) => { const resMessage = (error.response && error.response.data && error.response.data.message) || error.message || error.toString(); setLoading(false); setMessage(resMessage); } ); } else { setLoading(false); } }; return ( <div className="col-md-12"> <div className="card card-container"> <img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" /> <Form onSubmit={handleLogin} ref={form}> <div className="form-group"> <label htmlFor="username"> Username </label>{" "} <Input type="text" className="form-control" name="username" value={username} onChange={onChangeUsername} validations={[required]} />{" "} </div> <div className="form-group"> <label htmlFor="password"> Password </label>{" "} <Input type="password" className="form-control" name="password" value={password} onChange={onChangePassword} validations={[required]} />{" "} </div> <div className="form-group"> <button className="btn btn-primary btn-block" disabled={loading}> {" "} {loading && ( <span className="spinner-border spinner-border-sm"> </span> )}{" "} <span> Login </span>{" "} </button>{" "} </div> {message && ( <div className="form-group"> <div className="alert alert-danger" role="alert"> {" "} {message}{" "} </div>{" "} </div> )}{" "} <CheckButton style={{ display: "none" }} ref={checkBtn} />{" "} </Form>{" "} </div>{" "} </div> ); }; export default Login;
修复方案
1. 替换私有属性依赖的验证检查逻辑
你代码中checkBtn.current.context._errors依赖了react-validation库的内部私有属性,新版本库已经移除或修改了这个属性,导致访问时出现undefined,进而触发迭代错误。
将handleLogin中的验证检查代码替换为:
const isValid = form.current.validateAll(); if (isValid) { AuthService.login(username, password).then( () => { navigate("/profile"); window.location.reload(); }, (error) => { const resMessage = (error.response && error.response.data && error.response.data.message) || error.message || error.toString(); setLoading(false); setMessage(resMessage); } ); } else { setLoading(false); }
validateAll()方法本身会返回布尔值,表示表单是否通过所有验证,无需再通过CheckButton的内部属性获取错误。
2. 检查AuthService.login的实现
如果上述修改后仍报错,需检查AuthService.js中的login方法,确认是否存在对undefined值进行数组解构的情况(比如const [data, err] = await axios.post(...),但axios返回的是对象而非数组)。正确的异步请求处理应该是:
login(username, password) { return axios.post(API_URL + "signin", { username, password }) .then(response => { if (response.data.accessToken) { localStorage.setItem("user", JSON.stringify(response.data)); } return response.data; }); }
避免对非数组类型进行解构操作,这是触发该错误的常见原因之一。
内容的提问来源于stack exchange,提问作者haRpeR
相关产品推荐
相关产品推荐

