在我的react应用程序中,我有一个Login / Signup组件,我想按顺序完成以下任务:
渲染禁用的输入元素。
初始化firebase身份验证对象
成功初始化后,启用输入元素
将用户输入提交到我的Firebase数据存储区
将该请求的结果发送到我的应用程序的数据库中以进行进一步处理。
我的组件本质上看起来像这样:
function SignUpForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async function(e) {
e.preventDefault();
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.catch(function(error) {
console.error('error with logging in: ', error);
});
setAuthentication(true)
};
useEffect(() => {
firebase.auth().onAuthStateChanged(function(firebaseUser) {
if (firebaseUser) {
const myServiceUser = {
email: firebaseUser.email,
firebaseUid: firebaseUser.uid,
}
postToAppBackend('/signup', { ...myServiceUser })
.then(result => {
console.log('result', result);
});
} else {
//do something or nothing
}
});
}, [])
return (
<form>
//...some form stuff with an handleSubmit handler
</form>
)
}
问题
由于onAuthStateChanged会触发多次(据我不确定地收集),因此每次向我的后端添加多余的帖子时都会触发网络请求。
我尝试过的事情:
在useEffect
中设置状态标志,以防止在有用户if(firebaseUser)
为假的情况下进入myFlag
代码块。
类似...
const [myFlag, setMyFlag] = useState(false);
useEffect(() => {
firebase.auth().onAuthStateChanged(function(firebaseUser) {
if (firebaseUser && !myFlag) {
setMyFlag(true)
const myServiceUser = {
email: firebaseUser.email,
firebaseUid: firebaseUser.uid,
}
postToAppBackend('/signup', { ...myServiceUser })
.then(result => {
console.log('result', result);
});
} else {
//do something or nothing
}
});
}, [])
但是,myFlag始终为假(我想是因为闭包内部标志的性质?)。
我已经尝试了详尽的SO研究,发现:
Firebase Android onAuthStateChanged() fire twice after signInWithEmailAndPassword()
但是,似乎Firebase文档已更新,以反映此继续操作之前检查用户的策略。我的代码也反映了这一点。我只是不知道这与功能组件/挂钩反应如何。
问题
如何在onAuthStateChanged函数的多个触发器上,防止使用钩子在if块内多次运行代码?
也许我是在以一种非反应性/笨拙的方式来考虑这个问题,或者是误解了如何将观察者模型应用于功能性反应组件。
很高兴提供进一步的澄清。