How use React Routes with conditions and Redux?

Viewed 44

I'm struggling with creating an authentication with React Redux and Routes.

Depending on the variable responsible for authentication, the user gets a certain set of routes. But at the time of initial loading, when the variable has not yet received a value from the redux store, routes are displayed for a non-logged in user, i.e. registration page, and only then the necessary pages.

It turns out that every time you update the registration page flashes.

Code in routes.js:

export const RotesPage = ({ isAuthenticated }) => {
  if (isAuthenticated) {
    return (
      <div>
        <Switch>
          <Route path="/" exact>
            <MainPage />
          </Route>
          <Route path="/schedule" exact>
            <SchedulePage />
          </Route>
          <Route path="/tasks" exact>
            <TasksPage />
          </Route>
          <Route path="/money" exact>
            <MoneyPage />
          </Route>
          <Redirect to="/" />
        </Switch>
      </div>
    );
  }

  if (!isAuthenticated) {
    return (
      <Switch>
        <Route path="/login" exact>
          <LoginPage />
        </Route>
        <Route path="/register" exact>
          <RegisterPage />
        </Route>
        <Redirect to="/login" />
      </Switch>
    );
  }
};

Code in App.js:

import React, { useEffect } from "react";
import { BrowserRouter as Router } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import { loadUser } from "./actions/authAction"; 
import { AppNavbar } from "./layouts/components/AppNavbar";
import { RotesPage } from "./routes";

const App = () => {
  const dispatch = useDispatch(); 
  const auth = useSelector((state) => state.auth);
  const isAuthenticated = auth.isAuthenticated;

  useEffect(() => {
    dispatch(loadUser());
  }, [dispatch]);

  return (
    <Router>
      {isAuthenticated && <AppNavbar />}
      <RotesPage isAuthenticated={isAuthenticated} />
    </Router>
  );
};

export default App;

How can I fix it?

P.S. Sorry if I discribe it badly, 'cause I'm learning not only programming languages but English too.

P.P.S. It's my first Q here.

Thank you in advance =)

1 Answers

In your redux state set isLoading variable which initially will be true, once you get auth data set it to false.

Then in your App you can do something like:

  const auth = useSelector((state) => state.auth);
  const isAuthenticated = auth.isAuthenticated;
  const isLoading = auth.isLoading;

<Router>
  {isLoading ? (
    <div>Loading...</div>
  ): (
    <>
      {isAuthenticated && <AppNavbar />}
      <RotesPage isAuthenticated={isAuthenticated} />
    </>
  )}
</Router>
Related