E
E
eswift2020-10-02 18:13:30
JavaScript
eswift, 2020-10-02 18:13:30

How to display routes correctly depending on a condition in React?

Faced such a problem in writing authentication.

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

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

Code for 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>
    );
  }
};


App.js itself:
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 to fix this issue?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexander Cheremkhin, 2020-10-02
@Che603000

Your code is working correctly. The variable isAuthenticatedis initialized after an asynchronous call loadUser. Therefore, when the application starts, the user is not yet authorized and isAuthenticatedthe store is false.
Fix the logic. Options
1) call loadUser can be synchronous
2) show the first page the same for all users.
3) start the router after receiving a response to loadUser

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question