React / firebase应用程序在验证完成之前闪烁登录屏幕



当您注册/登录/刷新页面时,登录页面在进入正确页面之前闪烁。我试着放一个加载器,但它所做的只是在它闪烁之前做一个加载器动画,然后转到正确的页面。有什么办法不让这事发生吗?

function App(){
const [user, setUser] = useState();
const [loading, setLoad] = useState(true);
useEffect(() => {
const unsubscribe = onAuthStateChanged(getAuth(), setUser, setLoad(false))
return () => {unsubscribe()}
}, [])
const AuthenticatedRoute = ({children}) => {
let isAuthenticated;
if(user !=null){
isAuthenticated = true;
}else{
isAuthenticated = false;
}
if(!loading){
return isAuthenticated? children: <Navigate to="/signin"/>
}else{
return <Loading/>
}

}
const UnauthenticatedRoute = ({children}) => {
let isAuthenticated;
if(user !=null){
isAuthenticated = true;
}else{
isAuthenticated = false;
}
if(!loading){
return !isAuthenticated? children: <Navigate to="/home"/>
}else{
return <Loading/>
}

}
return(
<Router>
<div className="App">
{
<Routes>
<Route exact path="/" element={<UnauthenticatedRoute><PreHome/></UnauthenticatedRoute>}/>
<Route path='/home' element={<AuthenticatedRoute><Home/></AuthenticatedRoute>} />
<Route exact path="/signin" element={<UnauthenticatedRoute><Signin/></UnauthenticatedRoute>} />
<Route exact path="/signup" element={<UnauthenticatedRoute><Signup/></UnauthenticatedRoute>} />
</Routes>
}
</div>
</Router>
)
}

Sign Out code:这一行一直用于签出

<button onClick={() => signOut(getAuth())}>Sign Out</button>

Sign In code:

async function OnFormSubmit(e){
e.preventDefault();
const auth = getAuth();
try{
isLoading(true);
await signInWithEmailAndPassword(auth, email, pw)
isLoading(false);
}catch(err){
console.log(err)
}
}

问题

  1. 加载状态只是清除当有一个错误在onAuthStateChanged
  2. 路由保护器组件在内部声明另一个React组件。这是反模式。当新的"实例"出现时。每次父组件呈现App时,它将卸载/挂载组件的subReactTree。
  3. 组件在决定重定向或呈现路由内容之前,不等待用户的身份验证状态解析。

解决方案
  • 单独移动路由保护组件。渲染一个Outlet用于被渲染到的嵌套路由。这允许你将这些渲染为布局路由,而不是单独的包装器组件。
  • 使用适当的"加载";状态。使用未定义的user状态作为"加载状态">

例子:

import { Outlet, Navigate } from 'react-router-dom';
const AuthenticatedRoute = ({ user }) => {
if (user === undefined) return <Loading />;
return user
? <Outlet />
: <Navigate to="/signin" />;
};
const UnauthenticatedRoute = ({ user }) => {
if (user === undefined) return <Loading />;
return user
? <Navigate to="/home" />
: <Outlet />;
};

function App(){
const [user, setUser] = useState();
useEffect(() => {
const unsubscribe = onAuthStateChanged(getAuth(), setUser);
return unsubscribe;
}, []);
return(
<AuthContextProvider>
<Router>
<div className="App">
<Routes>
<Route element={<UnauthenticatedRoute user={user} />}>
<Route path="/" element={<PreHome />} />
<Route path="/signin" element={<Signin />} />
<Route path="/signup" element={<Signup />} />
</Route>
<Route element={<AuthenticatedRoute user={user} />}>
<Route path='/home' element={<Home />} />
</Route>
</Routes>
</div>
</Router>
</AuthContextProvider>
);
}

最新更新