我是react和firebase的新手。我正在尝试更改signInWithEmailAndPassword().then()中的isLoggedIn的值。但是我不能这样做,虽然已经调用了setIsLoggedIn(true),但它返回false。
import React, { useState, useContext } from 'react';
import { Link } from 'react-router-dom';
import fire from '../config/fire';
import { useHistory, useLocation } from 'react-router';
import { Context } from '../../App';
const SignIn = () => {
const context = useContext(Context);
// handling state of SignIn
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [emailErr, setEmailErr] = useState('');
const [passErr, setPassErr] = useState('');
// fetching the previous location
let history = useHistory();
let location = useLocation();
let { previousPath } = location.state || { previousPath: { pathname: '/' } };
const clearError = () => {
setEmailErr('');
setPassErr('');
};
const changeHistory = () => {
if (context.isLoggedIn) {
history.replace(previousPath);
}
};
const handelSignIn = () => {
clearError();
fire
.auth()
.signInWithEmailAndPassword(email, password)
.then((res)=> {
context.setIsLoggedIn(true);
changeHistory();
})
.catch((err) => {
switch (err.code) {
case 'auth/invalid-email':
setEmailErr('invalid e-mail, please enter a valid one.');
break;
case 'auth/user-not-found':
setEmailErr('Invalid e-mail address. Please enter the valid one.');
break;
case 'auth/wrong-password':
setPassErr('Invalid password.');
break;
default:
setEmailErr('Something wrong. Please try again.');
setPassErr('Something wrong. Please try again.');
}
});
};
return (
<div>
<Link to="/">Home</Link>
<div
style={{
display: 'flex',
height: '100vh',
justifyContent: 'space-around',
alignItems: 'center',
}}
>
<div className="signIn">
<input
type="email"
value={email}
placeholder="E-mail"
required
autoFocus
onChange={(e) => setEmail(e.target.value)}
/>
<p>{emailErr}</p>
<br/>
<input
type="password"
value={password}
placeholder="Password"
required
onChange={(e) => setPassword(e.target.value)}
/>
<p>{passErr}</p>
<br/>
<button onClick={handelSignIn}>Sign In</button>
</div>
</div>
</div>
);
};
export default SignIn;发布于 2021-07-07 13:15:20
更改状态是一个异步操作。到现在调用您的changeHistory时,状态实际上还没有更新。
解决这个问题的常用方法是使用useEffect钩子。但在这种情况下,将状态传递给调用可能更简单
const changeHistory = (isLoggedIn) => {
if (isLoggedIn || context.isLoggedIn) {
history.replace(previousPath);
}
};
context.setIsLoggedIn(true);
changeHistory(true);发布于 2021-07-07 13:17:01
问题是,您调用的是在上下文中异步设置isLoggedIn状态的context.setIsLoggedIn(true)。但是,您会立即调用changeHistory()并尝试在更新context.isLoggedIn之前读取它。
如果您希望依赖于更新后的状态,请尝试使用useEffect。
useEffect(()=>{
if(context.isLoggedIn) changeHistory();
},[context])您还可以在上下文提供程序中抽象此实现,而不是将此逻辑保留在您的组件中。在任何时候,您还可以读取当前登录用户的详细信息,或者通过在Auth对象上设置观察者来获取当前用户。这就是Firebase推荐你这样做的方式。请参阅此处的https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user。
https://stackoverflow.com/questions/68280231
复制相似问题