如何在私有路由组件中放置加载标志?
How can I put a loading sign inside the Private route component?
这是 PrivateRoute 组件:
import React from "react";
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { useAuth } from "../../Firebase/utils";
const PrivateRoute = ({ children }) => {
let currentUser = useAuth();
if (!currentUser) {
return <Navigate to="/login" />;
}
return children;
};
export default PrivateRoute;
App.js
<Route
path="/Page"
element={
<PrivateRoute>
<Page />
</PrivateRoute>
}
/>
有没有办法在 PrivateRoute 中加载?
这是我的 useAuth
:
export function useAuth() {
const [isLoading, setIsLoading] = useState(true); // checking the user's status
const [currentUser, setCurrentUser] = useState();
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setCurrentUser(user);
setIsLoading(false); // finished checking
});
return unsub;
}, []);
return { currentUser, isLoading };
}
这是App.js
function App() {
const { currentUser, isLoading } = useAuth();
const user = auth.currentUser;
const navigate = useNavigate();
console.log(currentUser?.email);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
console.log(uid);
// navigate("/Home");
// ...
} else {
// User is signed out
// ...
navigate("/login");
}
});
return () => {
unsub();
};
}, []);
return (
<div>
<div>
<Routes>
{!isLoading ? (
<>
<Route
path="/login"
element={
<SignInPage />
}
/>
<Route
path="/Home"
element={
<PrivateRoute>
<Homepage />
</PrivateRoute>
}
/>
</>
) : (
<>
<Route
path="/login"
element={
<SignInPage />
}
/>
</>
)}
<Route
path="/reset-password"
element={
<ResetPasswordPage />
}
/>
</Routes>
</div>
</div>
);
}
export default App;
useAuth
挂钩 returns 具有 isLoading
初始状态的对象:
export function useAuth() {
const [isLoading, setIsLoading] = useState(true);
const [currentUser, setCurrentUser] = useState();
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setCurrentUser(user);
setIsLoading(false); // finished checking
});
return unsub;
}, []);
return { currentUser, isLoading };
}
在 PrivateRoute
组件中访问此 isLoading
状态以有条件地呈现 null 或一些加载指示器,除 children
属性或重定向到登录路由之外的任何内容。
const PrivateRoute = ({ children }) => {
const { currentUser, isLoading } = useAuth();
if (isLoading) {
return null; // or loading spinner, etc...
}
if (!currentUser) {
return <Navigate to="/login" replace />;
}
return children;
};
您也可以只渲染所有路线,其中一些在必要时使用 PrivateRoute
包装器。
function App() {
const { currentUser } = useAuth();
const navigate = useNavigate();
console.log(currentUser?.email);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
console.log(uid);
// navigate("/Home");
// ...
} else {
// User is signed out
// ...
navigate("/login");
}
});
return () => {
unsub();
};
}, []);
return (
<div>
<div>
<Routes>
<Route path="/login" element={<SignInPage />} />
<Route
path="/Home"
element={
<PrivateRoute>
<Homepage />
</PrivateRoute>
}
/>
<Route path="/reset-password" element={<ResetPasswordPage />} />
</Routes>
</div>
</div>
);
}
这是 PrivateRoute 组件:
import React from "react";
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { useAuth } from "../../Firebase/utils";
const PrivateRoute = ({ children }) => {
let currentUser = useAuth();
if (!currentUser) {
return <Navigate to="/login" />;
}
return children;
};
export default PrivateRoute;
App.js
<Route
path="/Page"
element={
<PrivateRoute>
<Page />
</PrivateRoute>
}
/>
有没有办法在 PrivateRoute 中加载?
这是我的 useAuth
:
export function useAuth() {
const [isLoading, setIsLoading] = useState(true); // checking the user's status
const [currentUser, setCurrentUser] = useState();
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setCurrentUser(user);
setIsLoading(false); // finished checking
});
return unsub;
}, []);
return { currentUser, isLoading };
}
这是App.js
function App() {
const { currentUser, isLoading } = useAuth();
const user = auth.currentUser;
const navigate = useNavigate();
console.log(currentUser?.email);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
console.log(uid);
// navigate("/Home");
// ...
} else {
// User is signed out
// ...
navigate("/login");
}
});
return () => {
unsub();
};
}, []);
return (
<div>
<div>
<Routes>
{!isLoading ? (
<>
<Route
path="/login"
element={
<SignInPage />
}
/>
<Route
path="/Home"
element={
<PrivateRoute>
<Homepage />
</PrivateRoute>
}
/>
</>
) : (
<>
<Route
path="/login"
element={
<SignInPage />
}
/>
</>
)}
<Route
path="/reset-password"
element={
<ResetPasswordPage />
}
/>
</Routes>
</div>
</div>
);
}
export default App;
useAuth
挂钩 returns 具有 isLoading
初始状态的对象:
export function useAuth() {
const [isLoading, setIsLoading] = useState(true);
const [currentUser, setCurrentUser] = useState();
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setCurrentUser(user);
setIsLoading(false); // finished checking
});
return unsub;
}, []);
return { currentUser, isLoading };
}
在 PrivateRoute
组件中访问此 isLoading
状态以有条件地呈现 null 或一些加载指示器,除 children
属性或重定向到登录路由之外的任何内容。
const PrivateRoute = ({ children }) => {
const { currentUser, isLoading } = useAuth();
if (isLoading) {
return null; // or loading spinner, etc...
}
if (!currentUser) {
return <Navigate to="/login" replace />;
}
return children;
};
您也可以只渲染所有路线,其中一些在必要时使用 PrivateRoute
包装器。
function App() {
const { currentUser } = useAuth();
const navigate = useNavigate();
console.log(currentUser?.email);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
console.log(uid);
// navigate("/Home");
// ...
} else {
// User is signed out
// ...
navigate("/login");
}
});
return () => {
unsub();
};
}, []);
return (
<div>
<div>
<Routes>
<Route path="/login" element={<SignInPage />} />
<Route
path="/Home"
element={
<PrivateRoute>
<Homepage />
</PrivateRoute>
}
/>
<Route path="/reset-password" element={<ResetPasswordPage />} />
</Routes>
</div>
</div>
);
}