Create a Route That Redirects
Let’s first create a route that will check if the user is logged in before routing.
Add the following file in components src/components/AuthenticatedRoute.tsx
.
import { ReactElement } from "react";
import { Navigate, useLocation } from "react-router-dom";
import { useAppContext } from "../lib/contextLib";
export default function AuthenticatedRoute({
children,
}: {
children: ReactElement;
}): ReactElement {
const { pathname, search } = useLocation();
const { isAuthenticated } = useAppContext();
if (!isAuthenticated) {
return <Navigate to={`/login?redirect=${pathname}${search}`} />;
}
return children;
}
This simple component creates a Route
where its children are rendered only if the user is authenticated. If the user is not authenticated, then it redirects to the login page. Let’s take a closer look at it:
-
Like all components in React,
AuthenticatedRoute
has a prop calledchildren
that represents all child components. Example child components in our case would beNewNote
,Notes
andSettings
. -
The
AuthenticatedRoute
component returns a React RouterRoute
component. -
We use the
useAppContext
hook to check if the user is authenticated. -
If the user is authenticated, then we simply render the
children
component. And if the user is not authenticated, then we use theNavigate
React Router component to redirect the user to the login page. -
We also pass in the current path to the login page (
redirect
in the query string). We will use this later to redirect us back after the user logs in. We use theuseLocation
React Router hook to get this info.
We’ll do something similar to ensure that the user is not authenticated.
Next, add the following file in components src/components/UnauthenticatedRoute.tsx
.
import { cloneElement, ReactElement } from "react";
import { Navigate } from "react-router-dom";
import { useAppContext } from "../lib/contextLib";
interface Props {
children: ReactElement;
}
export default function UnauthenticatedRoute(props: Props): ReactElement {
const { isAuthenticated } = useAppContext();
const { children } = props;
if (isAuthenticated) {
return <Navigate to={"/"} />;
}
return cloneElement(children, props);
}
Here we are checking to ensure that the user is not authenticated before we render the child components. Example child components here would be Login
and Signup
. And in the case where the user is authenticated, we use the Navigate
component to simply send the user to the homepage.
The cloneElement
above makes sure that passed in state
is handled correctly for child components of UnauthenticatedRoute
routes.
Next, let’s use these components in our app.
For help and discussion
Comments on this chapter