? Private Route in react-router v6

Things are changing fast in WEB today, and react-router v6 is in beta already and around the corner. ?

This is just for learning purposes only, react-router v6 is still in beta, use at your own risk

Private routes in v5 and below were done in a spe…


This content originally appeared on DEV Community and was authored by Andrew Luca

Things are changing fast in WEB today, and react-router v6 is in beta already and around the corner. ?

This is just for learning purposes only, react-router v6 is still in beta, use at your own risk

Private routes in v5 and below were done in a specific way using a custom component mostly named PrivateRoute that was most of the times just a wrapper and composition of basic Route and Redirect e.g.

function PrivateRoute({ children, ...rest }) {
  let auth = useAuth();
  return (
    <Route
      {...rest}
      render={() => auth
        ? children
        : <Redirect to="/login" />
      }
    />
  );
}

function App() {
  return (
    <BrowserRouter>
      <Route path="/" component={Public} />
      <PrivateRoute path="/private" component={Private} />
    </BrowserRouter>
  );
}

But taking a look at v6 docs it seems that things changed a little bit, and we need to think a little bit different about it.

For info about all API reference see the link

Let's move on.

Some things that we used to create PrivateRoute have changed a little bit

  • Redirect is now Navigate
  • Route props changed and is just a stub component now
  • A new component Routes appearead

In v6, routes are rendered in such a manner

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Public />} />
        <Route path="/private" element={<Private />} />
      </Routes>
    </BrowserRouter>
  );
}

const Public = () => <div>public</div>;
const Private = () => <div>private</div>;

So as you can see, no more render props or component prop.
You need to pass a direct JSX element (don't worry about performance if you do)

Ok now let's take a look at Route component source code

/**
 * Declares an element that should be rendered at a certain URL path.
 *
 * @see https://reactrouter.com/api/Route
 */
export function Route(_props: RouteProps): React.ReactElement | null {
  invariant(
    false,
    `A <Route> is only ever to be used as the child of <Routes> element, ` +
      `never rendered directly. Please wrap your <Route> in a <Routes>.`
  );
}

wait a minute

Wait a minute where is the code? ? Well actually the parent component Routes will use the Route just as a host for the props and children, and do nothing more with the Route

For more info about Routes implementation see link

So how we do implement our PrivateRoute now? ? If we do some adjustments to PrivateRoute props, it will look like this

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Public />} />
        <PrivateRoute path="/private" element={<Private />} />
      </Routes>
    </BrowserRouter>
  );
}

But this will not work. Routes will just take the props of PrivateRoute and ignore it's body totally. Even a console.log inside PrivateRoute will not be shown.

So what we do? ? We do some more adjustments to PrivateRoute

function PrivateRoute({ children }) {
  const auth = useAuth();
  return auth ? children : <Navigate to="/login" />;
}

As you can see we changed Redirect to Navigate, and just return children if user is authenticated. And the usage of it also changes a little bit

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Public />} />
        <Route
          path="/private"
          element={
            <PrivateRoute>
              <Private />
            </PrivateRoute>
          }
        />
      </Routes>
    </BrowserRouter>
  );
}

As you can see PrivateRoute also moves to element prop.

The implementation of PrivateRoute can be done in multiple ways.

Here is a different implementation of PrivateRoute using Outlet

function PrivateOutlet() {
  const auth = useAuth();
  return auth ? <Outlet /> : <Navigate to="/login" />;
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/private-outlet" element={<PrivateOutlet />}>
          <Route element={<Private />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

The pros of this is that you can put multiple private sub routes under same route.

For a full example see this Codesandbox

That's all for today. Happy coding! ? ? ✨

Keep your users secure!

secure

Cover Photo by Maxim Zhgulev on Unsplash


This content originally appeared on DEV Community and was authored by Andrew Luca


Print Share Comment Cite Upload Translate Updates
APA

Andrew Luca | Sciencx (2021-09-21T23:37:28+00:00) ? Private Route in react-router v6. Retrieved from https://www.scien.cx/2021/09/21/%f0%9f%94%90-private-route-in-react-router-v6/

MLA
" » ? Private Route in react-router v6." Andrew Luca | Sciencx - Tuesday September 21, 2021, https://www.scien.cx/2021/09/21/%f0%9f%94%90-private-route-in-react-router-v6/
HARVARD
Andrew Luca | Sciencx Tuesday September 21, 2021 » ? Private Route in react-router v6., viewed ,<https://www.scien.cx/2021/09/21/%f0%9f%94%90-private-route-in-react-router-v6/>
VANCOUVER
Andrew Luca | Sciencx - » ? Private Route in react-router v6. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/21/%f0%9f%94%90-private-route-in-react-router-v6/
CHICAGO
" » ? Private Route in react-router v6." Andrew Luca | Sciencx - Accessed . https://www.scien.cx/2021/09/21/%f0%9f%94%90-private-route-in-react-router-v6/
IEEE
" » ? Private Route in react-router v6." Andrew Luca | Sciencx [Online]. Available: https://www.scien.cx/2021/09/21/%f0%9f%94%90-private-route-in-react-router-v6/. [Accessed: ]
rf:citation
» ? Private Route in react-router v6 | Andrew Luca | Sciencx | https://www.scien.cx/2021/09/21/%f0%9f%94%90-private-route-in-react-router-v6/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.