Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to build private route system in React

my App declaration looks like this

function App() {
  const [loggedIn, setLoggedIn] = useState(false);
  const [username, setUsername] = useState('')
  const [userId, setUserId] = useState(0)
  const [error, setError] = useState('')

  useEffect(() => {
    fetchSessionData(setLoggedIn, setUsername, setUserId, setError)
  }, [])

fetchSessionData calls the server and receives information about username and userId and sets the variables. Next i have routing

<Switch>
<Route exact path="/games/new">
              <PrivateRoute isLogged={loggedIn}>
                <MyComponent />
              </PrivateRoute>
            </Route>
<Switch/>

With PrivateRoute looking like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const PrivateRoute = ({ children, isLogged }: { children: JSX.Element, isLogged: boolean }): JSX.Element => {
    return (
        isLogged ? children : <Redirect to="/sign_in" />
    );
};

Its a simple system meant to assure that certain routes will only be accessible if the user is signed in. HOWEVER. Even if im actually signed in, the isLogged var seems to always be false.
I believe its because the routing part gets rendered before the answer from the server actually gets received and variables set.
Question is very simple, how to modify this architecture so the loggedIn variable is read after the response from the server?

>Solution :

You need a loading state or equivalent (e.g. loggedIn state initialized as null, and interpreting this null value as "loading").

Then do not render your <PrivateRoute> component while you are still loading:

{
  loggedIn !== null && <PrivateRoute isLogged={loggedIn}>
    <MyComponent />
  </PrivateRoute>
}

Or handle the loading state within <PrivateRoute> to prevent redirecting before loaded:

const PrivateRoute = ({
  children,
  isLogged
}: {
  children: JSX.Element,
  isLogged: boolean | null
}): JSX.Element => {
  return (
    isLogged === null
      ? "Checking user account..."
      : isLogged
        ? children
        : <Redirect to="/sign_in" />
  );
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading