I am encountering a problem with my private routing setup. Currently, I use the user variable in the App.js to determine if a user is logged in or not, in order to restrict access to private routes. The issue with this method is that if a user attempts to directly access a private page (such as "mysolutions"), they will be immediately redirected to the homepage due to the delay in fetching the user data from the database during the initial website load.
I would like to know how can I fix this issue.
My App.js code:
import React, { Suspense } from "react"
import { Navigate, Route, Routes } from "react-router-dom"
import rocketLoader from "./assets/animated_illustrations/rocketLoader.json"
import Layout from "./components/layouts/Layout"
import Meta from "./components/meta/Meta"
import LottieAnimation from "./components/reusable/LottieAnimation"
import ScrollToTop from "./components/reusable/ScrollToTop"
import { useAuthContext } from "./hooks/useAuthContext"
import "./App.css"
// lazy loading components
const Homepage = React.lazy(() => import("./pages/Homepage"))
const Dashboard = React.lazy(() => import("./pages/Dashboard"))
const MySolutions = React.lazy(() => import("./pages/MySolutions"))
const App = () => {
const { authIsReady, user } = useAuthContext()
return (
<>
<Meta routes={routes} />
<div>
<Suspense
fallback={
<div className="flex justify-center items-center min-h-screen">
<LottieAnimation animationDataFile={rocketLoader} />
</div>
}
>
<ScrollToTop>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Homepage />} />
<Route path="challenges" element={<Dashboard />} />
<Route
path="mysolutions"
element={user ? <MySolutions /> : <Navigate to="/" />}
/>
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
</Routes>
</ScrollToTop>
</Suspense>
</div>
</>
)
}
export default App
CodePudding user response:
You can use authIsReady variable from useAuthContext() for check the current user data inside the private route.
And with this variable you can simply add if condition to private route like :
<ScrollToTop>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Homepage />} />
<Route path="challenges" element={<Dashboard />} />
{authIsReady && (
<Route
path="mysolutions"
element={user ? <MySolutions /> : <Navigate to="/" />}
/>
)}
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
</Routes>
</ScrollToTop>
CodePudding user response:
I would create a loading page, which is shown to the user until the fetch is completed and we are able to decide if we can let advance to the private route or not. Would this solution work for you?