【发布时间】:2020-08-26 22:20:46
【问题描述】:
我还是 React 钩子的新手,我正在尝试调整 some code 以仅在用户在 Firebase 中经过身份验证时才允许访问某些路由。同时,如果用户键入不存在的路径,我希望用户被重定向到家。如果他在登出时试图访问受保护的路线之一,他也应该被重定向到家。这是我的 App.js 的样子:
import React, {Fragment, lazy, Suspense, useState, useEffect} from "react";
import {CssBaseline, MuiThemeProvider} from "@material-ui/core";
import {BrowserRouter, Redirect, Route, Switch} from "react-router-dom";
import theme from "./theme";
import GlobalStyles from "./GlobalStyles";
import * as serviceWorker from "./serviceWorker";
import Pace from "./shared/components/Pace";
import Firebase from "./firebase";
import FirebaseContext from "./firebase-context";
const firebase = new Firebase();
const LoggedInComponent = lazy(() => import("./logged_in/components/Main"));
const LoggedOutComponent = lazy(() => import("./logged_out/components/Main"));
function onAuthStateChange(callback) {
return firebase.auth.onAuthStateChanged(user => {
if(user) {
callback({loggedIn: true});
} else {
callback({loggedIn: false});
}
});
}
function App() {
const [user, setUser] = useState({loggedIn: false});
useEffect(() => {
const unsubscribe = onAuthStateChange(setUser);
return () => {
unsubscribe();
}
}, [setUser]);
console.log("logged in?", user.loggedIn);
return (
<BrowserRouter>
<FirebaseContext.Provider value={firebase}>
<MuiThemeProvider theme={theme}>
<CssBaseline/>
<GlobalStyles/>
<Pace color={theme.palette.primary.light}/>
<Suspense fallback={<Fragment/>}>
<Switch>
{user.loggedIn && <Route path="/c" component={LoggedInComponent}/>}
<Route exact path="/" component={LoggedOutComponent}/>
<Redirect to="/"/>
</Switch>
</Suspense>
</MuiThemeProvider>
</FirebaseContext.Provider>
</BrowserRouter>
);
}
serviceWorker.register();
export default App;
我遇到的问题是,当我登录并在主页上时。如果我尝试在 URL 中添加“/c”以访问受保护的部分,我会被重定向回主页,就像我没有登录一样。
当我在登录时重新加载主页时,我会得到 2 个控制台日志,一个说我没有登录,一个说我已经登录。而且我认为正在发生的事情是,在应用程序有机会渲染并看到我已登录之前,我被重定向了。这似乎可以通过以下事实得到证实,如果我注释掉我的重定向,我可以到达 @987654323 @。但是我没有得到该重定向的其他好处。
我难以理解的是为什么user.loggedIn 在第一次渲染组件时为假。
【问题讨论】:
-
“我难以理解的是为什么 user.loggedIn 在组件第一次渲染时为假。” - 因为您在 useState() 中将其设置为 false 作为初始值
-
好的,我明白了。但是,当然,如果我将初始状态loginIn 设置为true,并且我在注销时尝试加载受保护的路由,则在重定向到主页之前允许短暂的时间,所以看起来很冒险。那里的解决方案是什么?
-
可以初始化为null。所以现在你知道它是否为空,那么网络请求仍在继续,所以你可以加载微调器或其他东西。然后您可以使用从后端获得的数据更改状态
标签: reactjs firebase firebase-authentication react-router react-hooks