L
L
lexstile2021-11-28 21:36:03
React
lexstile, 2021-11-28 21:36:03

How to correctly configure routing through react-router-dom v. 5.3?

If isAuthenticated = false , public routes work, 404 page doesn't work.
If isAuthenticated = true , an error occurs:

react-dom.development.js:23798 Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
(If I remove public routes from App.jsx, then private ones start working)

How to do it right, when isAuthenticated = false , all public routes worked, there was a redirect from private routes, a 404 page for non-existent routes worked?

And to do when isAuthenticated = true, all private routes worked, there was a redirect from public routes, a 404 page worked for non-existent routes?

App.jsx
spoiler
<BrowserRouter>
                <Suspense fallback={<ScreenSpinner />}>
                  <Switch>
                    <PublicRoute isAuthenticated={isAuthenticated}>
                      <PublicRoutes />
                    </PublicRoute>
                    <PrivateRoute isAuthenticated={isAuthenticated}>
                      <PrivateRoutes />
                    </PrivateRoute>
                    <Route>
                      <NotFoundPage />
                    </Route>
                  </Switch>
                </Suspense>
              </BrowserRouter>

public route
spoiler
export const PublicRoute = ({ children = null, isAuthenticated = false, ...rest }) => {
  return (
    <Route
      {...rest}
      render={({ location }) =>
        !isAuthenticated ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: '/',
              state: { from: location },
            }}
          />
        )
      }
    />
  );
};

private route
spoiler
export const PrivateRoute = ({ children = null, isAuthenticated = false, ...rest }) => {
  return (
    <Route
      {...rest}
      render={({ location }) =>
        isAuthenticated ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: location },
            }}
          />
        )
      }
    />
  );
};

public routes
spoiler
const routes = [
  {
    path: 'login',
    component: lazy(() => import('pages/LoginPage')),
    exact: true,
  },
  {
    path: 'register',
    component: lazy(() => import('pages/RegisterPage')),
    exact: true,
  },
  {
    path: 'forgot-password',
    component: lazy(() => import('pages/ForgotPasswordPage')),
    exact: true,
  },
];

export const PublicRoutes = () => (
  <Switch>
    <Suspense fallback={<ScreenSpinner />}>
      {routes.map(({ component: Component, path, exact }) => (
        <Route path={`/${path}`} key={path} exact={exact}>
          <Component id={path} />
        </Route>
      ))}
    </Suspense>
  </Switch>
);

PrivateRoutes
spoiler
const routes = [
  {
    path: '',
    component: lazy(() => import('pages/HomePage')),
    exact: true,
  },
];

export const PrivateRoutes = () => (
  <Switch>
    <Suspense fallback={<ScreenSpinner />}>
      {routes.map(({ component: Component, path, exact }) => (
        <Route path={`/${path}`} key={path} exact={exact}>
          <Component id={path} />
        </Route>
      ))}
    </Suspense>
  </Switch>
);

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question