Search code examples
reactjsreact-routerreact-router-domreact-router-v4

Conditional routes not working in React Router


I want to allow routes only if the user has the appropriate role to visit them. I do the check both on the frontend and the backend, however when using Switch something is not working.

 {localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("CONTRIBUTOR") &&
              <>
                {/* Contributor Routes */}
                <Route exact path="/contributor/upload" component={ContributorUploadPage}/>
                <Route exact path="/contributor/edit/:rawContentId" component={ContributorEditPage}/>
                <Route exact path="/contributor" component={ContributorListPage}/>
               </> }

              {localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("EDITOR") &&
                //{/* Editor Routes */}
                <>
                <Route exact path="/editor/search" component={EditorSearch}/>
                <Route path="/editor/upload" component={EditorUploadPage}/>
                <Route exact path="/editor/edit/:finalContentId" component={EditorEditPage}/>
                <Route exact path="/editor" component={EditorListPage}/>
                </>
              }

              {localStorage.getItem("roles") && localStorage.getItem("roles").split(",").map(item => (item === "SUB_PERVIEW" || item === "SUB_SUBSCRIPTION" 
              || item === "SUB_FREE" ? true : false)) &&
              <>
                {/* Subscriber Routes */}
                <Route exact path="/content" component={ContentPage}/>
              </> }

<Route path="/404" component={NotFoundPage}/>
              <Redirect to="/404"/>

If I now go to /editor, even if I don't have an appropriate role, I'm not being redirected to /404. If I remove all of the conditions, the /404 page is rendered.


Solution

  • You could simply define a protected route component and reuse it:

    import React from "react";
    import { Route, Redirect } from "react-router-dom";
    
    const isContributor = localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("CONTRIBUTOR");
    
    const ProtectedRoute = ({ component: Component, ...rest }) => {
    
      return (
        <Route
          {...rest}
          render={(props) =>
            isContributor ? <Component {...props} /> : <Redirect to="/404" />
          }
        />
      );
    };
    
    

    Then use that route as follows:

     <ProtectedRoute exact path="/editor" component={EditorListPage}/>