有一个表单,用户填写此信息(如电子邮件和密码),然后点击提交按钮开始付款流程。但是在我让该人继续之前,我需要检查用户是否已经在数据库中拥有具有相同电子邮件地址的电子邮件。当我执行 setRetrievedEmailAddress 并将我检索的电子邮件地址(如果存在)设置为变量retrieveedEmailAddress 时,它会立即更新,但是当我第二次单击状态更改的按钮时,它会立即更新,如下所示下面的屏幕截图。我不能在事件处理程序中使用 useEffect 钩子,所以这是不可能的。我需要立即更新状态,否则此人将继续付款过程并最终支付两次,因为他已经在我们这里有一个帐户。所以我的问题是,如何立即更新状态?
g.add_legend(loc=9)
答案 0 :(得分:1)
发生这种情况是因为您正在调用异步调用,因此当您调用 console.log(retrievedEmailAddress)
时,信息尚未到达。因此,满足您要求的最佳方法是在答案中进行验证:
database.collection("users").where("email", "==", "nonpaidmembership@gmail.com")
.get()
.then((querySnapshot) => {
if (querySnapshot.exists) {}
querySnapshot.forEach((doc) => {
if (doc.exists) {
setRetrievedEmailAddress(doc.data().email);
console.log(doc.id, " => ", doc.data().email);
//here is safe to validate your data
if (doc.data().email != null) {
setError('User Already exists, please choose a different email');
console.log("user already exists");
}
else {
//Start payment Process
}
}
else {
console.log("doc doesnt exist");
}
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
console.log(retrievedEmailAddress); // here the information will no be present the first time
答案 1 :(得分:0)
所以,您的问题是 setRetrievedEmailAddress
需要一些时间来更新 retrievedEmailAddress
试试这个...
setRetrievedEmailAddress(prevState => (doc.data().email));
答案 2 :(得分:0)
setState 是异步的,你在更新它的函数中没有得到它的更新值, 创建一个已验证的状态;
const [verified, setVerified] = useState(false);
使用下面提到的 useEffect 钩子
useEffect(() => {
if(verified){
// proceed to payment
// ....
// at the end don't forget to setVerified(false)
}
}, [verified])
答案 3 :(得分:0)
您正在使用异步函数...
所以应该在请求前加上 await
关键字
await database.collection("users").where("email", "==", "nonpaidmembership@gmail.com")
.get()
此外,在任何情况下,您都不会将 retrievedEmailAddress
设置为 null
...这将是有问题的
对于场景
if (retrievedEmailAddress != null)
将为真且付款流程不会开始)