1110
1110

Reputation: 6839

How to redirect to route when all routes are loaded dynamically based on condition?

This is my code to load routes (react router dom 5) based on user object in context.

function App() {
  return (
      <UserContextProvider>
        <BrowserRouter>
          <Navigation/>
        </BrowserRouter>
      </UserContextProvider>
  );
}

Navigation code. Here I conditionally load routes.

function Navigation() {

  const { contextState } = useUserContext();

  const routes = contextState.user ? routesAuthenticated : routerUnauthenticated;
  
  return (
    <Switch>
        {routes.map((route, index) => {
            return (
                <Route
                    key={index}
                    path={route.path}
                    exact={route.exact}
                    render={(props: RouteComponentProps) => (
                        <route.component name={route.name} {...props} {...route.props} />
                    )}
                />
            );
        })}
    </Switch>
  );
}

You see that based on context user object I load different routes. Routes are simple config files:

export const routerUnauthenticated: IRoute[] = [
  {
    path: '/register',
    name: 'Register page',
    component: RegisterPage,
    exact: false,
  },
  {
      path: '/login',
      name: 'Login page',
      component: LoginPage,
      exact: false,
  }...

Problem is I am on route http://localhost:3000/login and after succesfull login I got blank page with route http://localhost:3000/login. Before login I have 3 routes login/register/home. After login I have 5 routes dashboard/profile... What I am trying to do is after successfull login get to /dashboard route but because of my idea with dynamic routes loading I can't figure how to navigate.

Login is simple fake function in my context:

try {
        setContextState({ type: ContextActions.LOGIN_IN_PROGRESS });

        setTimeout(() => {console.log({ userId: 1, username: '[email protected]' });
          setContextState({ type: ContextActions.LOGIN_SUCCESS, payload: { user: { userId: 1, username: '[email protected]' } } });
        }, 3000);
      } catch(error) {
        setContextState({ type: ContextActions.LOGIN_ERROR });
      }

Upvotes: 6

Views: 776

Answers (2)

Maradox
Maradox

Reputation: 640

This is the most common protectedRoute component that is being used widely.

const App = () => {
    const { user } = useAuth();
  return (
    <Router>
        <Route path="/public">
          <Public />
        </Route>
        <Route path="/login">
          <Login />
        </Route>
        <PrivateRoute path='/protected' user={user}>
          <Protected />
        </PrivateRoute>
      </div>
    </Router>
  )
}

const PrivateRoute = ({ children, user, ...rest }) => (
    <Route {...rest} render={({ location }) => {
      return user === null
        ? <Redirect to={{
            pathname: '/login',
            state: { from: location }
          }}
        />
        : children
    }} />
)

Upvotes: 0

Gandalf
Gandalf

Reputation: 51

Why not just load all the routes? You can use a custom Route component to see if the contextState.user exists Kind of like a protected route which redirects to /login or /register if a non authenticated user goes to that route.

Upvotes: 2

Related Questions