英文:
Two clicks needed for log in
问题
我必须点击两次登录按钮才能检查数据。有人能解释为什么吗?
我正在创建一个论坛网站,在我的登录页面上,用户必须点击两次按钮,然后代码才会验证并响应提供的数据。
以下是在按钮点击时触发的 handle submit:
const [values, setValues] = useState({
email: '',
password: ''
})
const navigate = useNavigate();
const [errors, setErrors] = useState({})
const handleInput = (e) => {
setValues(prev => ({ ...prev, [e.target.name]: [e.target.value] }))
}
const handleSubmit = (e) => {
e.preventDefault()
setErrors(Validation(values))
if (errors.password === "" && errors.email === "") {
axios.post('http://localhost:8081/login', values)
.then(res => {
if (res.data.errorMessage === 'Success') {
navigate('/dashboard');
} else {
console.log(res.data.errorMessage);
}
})
.catch(err => console.log(err));
}
}
PS:当填写不正确时,验证返回错误消息。
我对Node.js和React都很新,如果有人能解释,将会帮助很大!
英文:
I have to click log in twice before it chacks the data. Can someone help why?
I'm creating a forum website and on my log-in page the user has to click the button twice before it the code validates and responds to the given data.
here is my handle submit which is triggered on button click.
const [values,setValues] =useState({
email: '',
password: ''
})
const navigate =useNavigate();
const [errors, setErrors] = useState({})
const handleInput = (e) => {
setValues(prev => ({...prev, [e.target.name]: [e.target.value]}))
}
const handleSubmit = (e) => {
e.preventDefault()
setErrors(Validation(values))
if(errors.password === "" && errors.email === ""){
axios.post('http://localhost:8081/login', values)
.then(res => {
if(res.data.errorMessage ==='Success'){
navigate('/dashboard');
}
else{
console.log(res.data.errorMessage);
}
})
.catch(err => console.log(err));
}
};
PS validation returns error messages when spots are not filled properly
I'm new to nodejs and react so if anyone could explain it would be a huge help!
答案1
得分: 0
正如我在评论中提到的,我最好的猜测是这与useState设置方法不立即反映更改有关。在你的情况下,你试图在调用setErrors
后立即访问errors
上的属性。然而,setErrors
不仅会异步执行,而且它的新值甚至不能从当前闭包中访问。具体来说,handleSubmit
变成了所谓的“陈旧闭包”,因为errors
仍然引用初始的空对象{}
。只有在重新渲染后,handleSubmit
才会以新的错误值重新定义;这就是为什么需要点击两次的原因。
要修复你的情况,你只需要通过将其存储在本地变量中来使自己同步访问新的错误,就像这样:
const handleSubmit = (e) => {
e.preventDefault()
const newErrors = Validation(values);
setErrors(newErrors)
if(newErrors.password === "" && newErrors.email === ""){
axios.post('http://localhost:8081/login', values)
.then(res => {
if(res.data.errorMessage === 'Success'){
navigate('/dashboard');
}
else{
console.log(res.data.errorMessage);
}
})
.catch(err => console.log(err));
}
};
英文:
As I mentioned in my comment, my best guess is that this is related to The useState set method is not reflecting a change immediately. In your case, you are trying to access the properties on errors
immediately after calling setErrors
. However, not only will setErrors
execute asynchronously, but its new value won't even be accessible from the current closure. Specifically, handleSubmit
becomes what is known as a "stale closure" because errors
still references the initial empty object {}
. Only after rerendering does handleSubmit
get redefined with the new error values; that's why it takes 2 clicks.
To fix your case, you just need to give yourself synchronous access to the new errors, which can be done simply by storing it in a local variable, like so:
const handleSubmit = (e) => {
e.preventDefault()
const newErrors = Validation(values);
setErrors(newErrors)
if(newErrors.password === "" && newErrors.email === ""){
axios.post('http://localhost:8081/login', values)
.then(res => {
if(res.data.errorMessage ==='Success'){
navigate('/dashboard');
}
else{
console.log(res.data.errorMessage);
}
})
.catch(err => console.log(err));
}
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论