0

I have a single-page React application with a very basic setup (compressed here):

function App() {
  const [ userLogin, setUserLogin ] = useState(null);

  useEffect(() => {
    try {
      const result = AuthService.getAuthenticatedUser();
      setUserLogin(result);
    } catch (error) {
      console.error('Error fetching login data: ', error);
    }
  }, []);

  function RequireAuthentication({ redirectTo }) {
    return userLogin ? <Outlet /> : <Navigate to={redirectTo} />;
  }

  return (
    <React.StrictMode>
      <BrowserRouter>
        <Routes>
          <Route path="/login" element={ <LoginPage /> } />
          <Route path="/logout" element={ <LogoutPage /> } />
          <Route path="/" element={ <RequireAuthentication redirectTo="/login" /> }>
            <Route path="/" element={ <div>lol</div> } />
            <Route path="option1" element={ <div>option1</div> } />
            <Route path="option2" element={ <div>option2</div> } />
            <Route path="option3" element={ <div>option</div> } />
          </Route>
          <Route path="*" element={ <Navigate to="/" /> } />
        </Routes>
      </BrowserRouter>
    </React.StrictMode>
  );
}

Right now my AuthService just looks at local storage and I will expand that to something that makes a REST API call to verify the persisted token is actually valid (and that the API is generally available).

I have two questions here, one of which I have a workaround answer to:

  1. What is the idiomatic way to add a header/navbar that is hidden on the login page? (workaround below, and this is just for bonus points)
  2. The primary question: My implementation currently resides in useEffect, which throws off the RequireAuthentication function. How do I force that to be evaluated and run the redirect only after the useEffect function completed?

I tried to put the call to AuthService.getAuthenticatedUser in the RequiredAuthentication function, but I am having problems making inline calls to Rest APIs and the solution I was pointed to was to use useEffect with async and await.

For my workaround on hiding a header, my workaround is something like this, where I render it as a parent above the BrowserRouter element:

return (
   <div className={ useLoggedIn ? 'hidden' : undefined }>This is my nav bar.</div>
);

Other things I looked at:

  • I found this post; however, it is 4 years old and I am sure React has updated
  • This post only has a single child element.
  • This is also 4 years old
  • etc.
el n00b
  • 1,957
  • 7
  • 37
  • 64

0 Answers0