【发布时间】:2022-01-07 18:59:19
【问题描述】:
我有两个输入的登录功能组件。它是受控组件,因此电子邮件和密码绑定到状态(用户)。输入是我使用的一个组件,而不是输入标签(重构输入)。我可以使用 handleInputChange 事件处理程序通过输入值更改状态用户(电子邮件和密码),我也可以使用 handleSubmit 处理程序提交表单。
在我尝试使用 yup 验证表单并捕获错误之前,一切都很好。我声明了错误状态以保存我得到的错误。我想捕获错误并显示在“div className="alert"”中,并且我想在不存在错误时将用户发布到服务器。我在 validate() 函数中看到了与 yup 相关的错误,但是当我更改错误状态时(setErrors([...er.errors]))我发现错误状态为空(console.log(errors.length))。
这里是登录组件:
import axios from "axios";
import queryString from "query-string"
import { useEffect, useRef,useState } from "react";
import React from "react"
import {useLocation, useRouteMatch,useParams} from "react-router-dom"
import Input from "./input";
import * as yup from 'yup';
const Login = () => {
useEffect(async()=>{
console.log(errors)
},[errors])
var [user,setUser]=useState({email:'',password:''});
var [errors,setErrors]=useState([])
let schema=yup.object().shape({
email:yup.string().email("ایمیل نامعتبر است").required("فیلد ایمیل الزامیست"),
password:yup.string().min(8,"رمز عبور باید حداقل 8 رقم باشد")
})
const validate=async()=>{
try {
const resultValidate=await schema.validate(user, { abortEarly: false })
}
catch(er){
console.log(er.errors)
setErrors([...er.errors])
}
}
const handleSubmit= async(e)=>{
e.preventDefault();
await validate();
console.log(errors.length)
if(errors.length===0){
alert("X")
const response= await axios.post("https://reqres.in/api/login",user)
console.log(response)
}
}
const handleInputChange=async(e)=>{
setUser({...user,[e.currentTarget.name]:e.currentTarget.value})
}
return (
<>
<div id="login-box" className="col-md-12">
{errors.length!==0 && (<div className="alert">
<ul>
{errors.map((element,item)=>{
return(
<>
<li key={item}>
{element}
</li>
</>
)
})}
</ul>
</div>) }
<form onSubmit={handleSubmit} id="login-form" className="form" action="" method="post">
<h3 className="text-center text-info">Login</h3>
<Input onChange={handleInputChange} name="email" id="email" label="نام کاربری" value={user.email}/>
<Input name="password" onChange={handleInputChange} id="password" value={user.password} label="رمز عبور"/>
{/* <div id="register-link" className="text-right">
<a href="#" className="text-info">Register here</a>
</div> */}
<input type="submit" className="btn btn-primary" value="ثبت"/>
</form>
</div>
</>
);
}
export default Login;
这里是输入组件:
import {Component} from "react"
class Input extends Component {
render() {
return <>
<div className="form-group">
<label htmlFor="username" className="text-info">{this.props.label}</label><br/>
<input type="text" onChange={this.props.onChange} name={this.props.name} id={this.props.id} className="form-control" value={this.props.value} />
</div>
</>;
}
}
export default Input;
我知道 setStates(在我的组件 setErrors 中)是异步的并且它是延迟的。我尝试使用简单的数组变量(命名为错误)而不是状态和钩子,但猜猜看,当我更改错误变量时它没有重新呈现页面!当然,我用这种方式在页面中看不到错误。
我尝试使用useEffect() 解决此问题,我决定检查验证错误并在useEffect 中发布,而不是handleSubmit 处理程序:
useEffect(async()=>{
if(errors.length===0){
const response= await axios.post("https://reqres.in/api/login",user)
console.log(response)
}
console.log(errors)
}, [errors])
现在我在输入无效时看到错误。当我输入有效值时,仍然有相同的错误! 看起来我无法更新错误状态,即使输入有效值,我也会收到以前的错误!我尽量不使用基于类的组件。我该怎么办?
【问题讨论】:
标签: javascript reactjs react-hooks react-functional-component