DEV Community

Saleh Mubashar
Saleh Mubashar

Posted on • Edited on

Conditional Routing with React Router V6

Lets take a look at how to render a component on a certain route conditionally using React router v6 features.

Check out my latest blog post on Framer Motion!


Perquisites

Install React Router V6 using the following npm command:
npm install react-router-dom@6

Next, import the following components from react router dom.



import {
  BrowserRouter as Router,
  Route,
  Routes,
  Navigate,
} from "react-router-dom";


Enter fullscreen mode Exit fullscreen mode

Cresting the Routes

Firstly wrap all the content of your page inside the return function inside the . Next, create the induvial routes inside the component.



return (
    <Router>
      <Routes>
        <Route exact path="/" element={<Home />} />
        <Route exact path="start" element={<Start />} />
      </Routes>
    </Router>
)


Enter fullscreen mode Exit fullscreen mode

For each route, we have the path and the element props, these tell the path on the address bar and the component to be rendered out respectively. The exact prop ensures that the *location.pathname * will match exact location path.

Conditional Routing

Lets say we want to render a component only if a state is true for example if a user is logged in, we can do that like this:



<Route
  exact
  path="start"
  element={
    loggedIn ? (
      <Start />
    ) : (
      <Navigate replace to={"/"} />
    )
  }
/>


Enter fullscreen mode Exit fullscreen mode

Basically here we are checking if the loggedIn state is true. If it is, we return the Start component, however if it is false, we redirect the user to the homepage using the Navigate element.

The replace prop simply replaces the current location with the given path instead of adding on to it.

Example

For example we have a state that we can toggle with a button. We can add a function on the button to toggle the state which in turn shows/hides the component/route.



import * as React from "react";
import {  useState } from "react";
import { BrowserRouter as Router, Routes,Route,Navigate } from "react-router-dom";
import Start from "./Start";

function App() {
  const [loggedIn, setLoggedIn ] = useState(true)
  const toggleRoute = () =>{
    setLoggedIn(!loggedIn)
  }
  return (
    <>
    <Router>
      <Routes>
        <Route
          exact
          path="start"
          element={loggedIn ? <Start /> : <Navigate replace to={"/"} />}
        />
      </Routes>
    </Router>
    <button onClick={toggleRoute}>Toggle</button>
    </>
  );
}
export default App;


Enter fullscreen mode Exit fullscreen mode

Thanks for reading!
Check out my blog too!

Top comments (12)

Collapse
 
shuy62181886 profile image
Shuy

I am a little late, but I was wondering, if you have multiple route that use the same condition as you (with the loggedIn boolean value), is there a way to move the condition out of the all those round and somehow wrap those routes with the condition to avoid repitition?

Collapse
 
salehmubashar profile image
Saleh Mubashar

perhaps you could create a routes array and the map it out?

Collapse
 
salehmubashar profile image
Saleh Mubashar • Edited

hmm, something like this may clear your mind.
For example we have a state that we can toggle with a button. We can add a function on the button to toggle the state which in turn shows/hides the component/route

import * as React from "react";
import {  useState } from "react";
import { BrowserRouter as Router, Routes,Route,Navigate } from "react-router-dom";
import Start from "./Start";

function App() {
  const [loggedIn, setLoggedIn ] = useState(true)
  const toggleRoute = () =>{
    setLoggedIn(!loggedIn)
  }
  return (
    <>
    <Router>
      <Routes>
        <Route
          exact
          path="start"
          element={loggedIn ? <Start /> : <Navigate replace to={"/"} />}
        />
      </Routes>
    </Router>
    <button onClick={toggleRoute}>Toggle</button>
    </>
  );
}
export default App;

Enter fullscreen mode Exit fullscreen mode
 
salehmubashar profile image
Saleh Mubashar

yes that is a good use. You can set user roles with this so that only specific people or users
can access the Route. I recently created an app in which I wanted the users to be able to see a Route if they
had solved a quiz, so this trick came in handy

Collapse
 
arsad1 profile image
Arsadi

I have an issue.

I do conditional render element like you did. But, I use permission instead of loggedIn. So I check if the user have permission to this route. the permission I get from backend API, and I store it on localStorage.

When the unAuthorized user has logged in, and logged out, next when the Authorized user logged in (user has permission) the route still protected. I still got redirected even the checker function return true (which is should return me the Element, not Redirect).

It will works fine when I refresh the page as Authorized user on the /dashboard routes (this is first page when user successfully logged in). Maybe the React Router not re-rendered automatically?.

I've force refresh the page if the user logged out. But it doesn't solve the problem.

Do you have some advice on this?

Thank you.

Collapse
 
salehmubashar profile image
Saleh Mubashar

Yes I think there is a rendering issue.
You can try to create a custom Protected Route
Check out this link for more info .
This is what is suggest. Hope it works

Collapse
 
jps27cse profile image
Jack Pritom Soren

Thank you, helpful for me!

Collapse
 
lnquy065 profile image
Quy Luong

Clean solution, thanks for sharing 👏

Collapse
 
idanref profile image
Idan Refaeli

Awesome!

Collapse
 
idanref profile image
Idan Refaeli

Awesome, thanks!