我刚刚使用React和Firebase在我的Web应用程序中实现了身份验证。效果很好,但我意识到,对于每次页面更改或刷新,它首先会将状态默认为空用户。 AuthChangeListener立即触发并检测到已登录内容并重新渲染屏幕。我知道这是React的工作方式,但是如何将当前用户状态默认为当前登录的用户。到目前为止,它看起来像是快速闪烁。
export default class Router extends Component {
constructor(props)
{
super(props);
this.state = {
user:null
}
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
}
authListener()
{
// fetch current user
auth.onAuthStateChanged((user) => {
if (user) {
this.setState({
user:user
});
}
else {
this.setState({
user:null
});
}
});
}
componentDidMount()
{
this.authListener();
}
render()
{
return(
<BrowserRouter>
<Switch>
<Route exact path="/donate" component = {() => <Donate user={this.state.user} />}/>
<Route exact path="/" component = {() => <Donate user={this.state.user} />}/>
<Route exact path="/news" component = {News}/>
<Route exact path="/about" component = {About}/>
<Route exact path="/auth" component = {() => <Auth user={this.state.user} login={this.login} logout={this.logout}/>}/>
<Route exact path="/funded" component = {Funded}/>
<Route exact path="/contact" component = {Contact}/>
<Route path="*" component={Error} />
</Switch>
</BrowserRouter>
)
}
}
答案 0 :(得分:0)
我记得碰到过这样的事情。不幸的是,onAuthStateChanged
在会话状态更改(用户登录/注销)时起作用,但是它不会告诉您是否有活动的会话。
我发现处理此问题的唯一方法是使用重复计时器检查currentUser
属性,并将state属性设置为false,直到结果返回null
或当前会话为止,尝试次数。计时器运行时,我在屏幕上有一个叠加层和一个旋转计时器,让用户知道该应用程序正在运行。如果结果为null(无用户会话),则显示登录表单。如果活动会话又回来了,请显示相应的组件。
constructor(){
super();
this.state = { sessionChecks: 0 };
this.auth = firebase.auth();
this.checkActiveUser = this.checkActiveUser.bind(this);
}
checkActiveUser(){
const loggedUser = this.auth.currentUser;
// set this to the amount of tries you want
if( !loggedUser && this.state.sessionChecks < 3) {
setTimeout( () => {
// no user session, check again
this.setState({ sessionChecks: ( sessionChecks + 1 ) });
this.checkActiveUser();
}, 500); // change the time to what you want
} else if(loggedUser) {
// there is an active user, run your code here
}
}
仍然需要使用计时器检查用户会话的另一个选项是使用reload
的{{1}}方法,该方法返回一个可以在异步代码中使用的承诺:>
https://firebase.google.com/docs/reference/js/firebase.User?authuser=0#reload
编辑
为了立即检查用户会话,我想到的解决方案是创建一个包含所有路由的组件,并将该组件添加到主应用程序文件中。
这是主应用程序文件(index.js)
currentUser
const App = => <Provider store={appStore}>
<Router>
<Routes />
</Router>
</Provider>;
被传递给ReactDOM的render方法。路由器是通过以下方式导入的BrowserRouter:App
。路由是所有路由的组成部分。该组件在应用程序的生命周期中仅安装了一次。
这里是import { BrowserRouter as Router } from "react-router-dom";
组件(至少是其中的相关部分):
<Routes />
现在,在检查代码的同时,您不仅可以一直显示登录组件,还可以在登录组件上显示带有微调器和消息的覆盖图,并且当检查完成时,可以独立显示是否有活动的会话或否,请隐藏该覆盖并显示渲染的组件,无论是登录组件还是用于特定路线的组件。
希望这会有所帮助。