DEV Community

ugurgunes95
ugurgunes95

Posted on

1

React JS Conditional Routing Logic Implementation

React JS Conditional Routing Logic Implementation

Setup

  • First things first we need to create our basic react application. In order to do that, open a terminal in a preferred location on your pc and run this command: npm create vite@latest.

Note that; in this example I have used vite. But you can also use create-react-app etc.

  • After the command above it will ask you for a project name, framework and variant. I am going to use TypeScript React template.

  • When you've created the project run this command to all the install dependencies and react-router;

  npm install && npm install react-router-dom@latest
Enter fullscreen mode Exit fullscreen mode

or if you're using yarn;

  yarn install && yarn add react-router-dom@latest
Enter fullscreen mode Exit fullscreen mode
  • Now I am going to delete unnecessary files etc. At the end of the setup section your file tree will look like this:
  ugur@gunes:~/Development/reactjs/test$ tree --dirsfirst
  .
  ├── public
  ├── src
  │   ├── index.css
  │   ├── Layout.tsx
  │   ├── main.tsx
  │   └── vite-env.d.ts
  ├── index.html
  ├── package.json
  ├── tsconfig.json
  ├── tsconfig.node.json
  └── vite.config.ts

  3 directories, 9 files
Enter fullscreen mode Exit fullscreen mode
  • That's it for our basic setup.

Configuration

So let's create our pages which we're going to use in the next steps.

Creating Pages

  • I'll create a directory named pages in src folder. And inside of that directory I'll also create two other directories just to make the situation more clear.
  • I am creating AuthorizedPages and UnauthorizedPages directories in the src/pages folder.
  • And I will just create two components; one for AuthorizedPages(Home.tsx) and one for UnauthorizedPages(Login.tsx).

-

  // Home.tsx

  import { useContext } from "react";
  import { AuthContext } from "../../context/AuthContext.tsx";

  const Home = () => {
    const { setLoginContext } = useContext(AuthContext);
    return (
      <section>
        <h1>Home Page</h1>
        <button onClick={() => setLoginContext(false)}>Logout</button>
      </section>
    );
  };

  export default Home;
Enter fullscreen mode Exit fullscreen mode

-

  // Login.tsx

  import { useContext } from "react";
  import { AuthContext } from "../../context/AuthContext.tsx";

  const Login = () => {
    const { setLoginContext } = useContext(AuthContext);
    return (
      <section>
        <h1>Login Page</h1>
        <button onClick={() => setLoginContext(true)}>Login</button>
      </section>
    );
  };

  export default Login;
Enter fullscreen mode Exit fullscreen mode
  • Here's how it looks at the end:
  .
  ├── public
  ├── src
  │   ├── pages
  │   │   ├── AuthorizedPages
  │   │   │   └── Home.tsx
  │   │   └── UnauthorizedPages
  │   │       └── Login.tsx
  │   ├── index.css
  │   ├── Layout.tsx
  │   ├── main.tsx
  │   └── vite-env.d.ts
  ├── index.html
  ├── package.json
  ├── tsconfig.json
  ├── tsconfig.node.json
  └── vite.config.ts

  6 directories, 11 files
Enter fullscreen mode Exit fullscreen mode
  • Check the page files' content on the github repository.

Creating AuthContext

In this section we'll create AuthContext. I will not implement authentication logic to make this article short and less complicated. Instead we'll just simulate it.

  • I am creating a directory called context under our src folder.
  • In this directory we'll create 4 files: AuthContext.tsx, AuthContextType.tsx, AuthContextProviderPropType.tsx and AuthContextInitialState.tsx.
  • Creating 4 different files is not necessary but I just like to seperate them.
  • File's contents will be like that:
  // AuthContext.tsx

  import { createContext, useState } from "react";
  import { AuthContextType } from "./AuthContextType.tsx";
  import { AuthContextInitialState } from "./AuthContextInitialState.tsx";
  import { AuthContextProviderPropType } from "./AuthContextProviderPropType.tsx";

  export const AuthContext = createContext<AuthContextType>(
  AuthContextInitialState,
  );

  export const AuthContextProvider = ({
  children,
  }: AuthContextProviderPropType) => {
  const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const setLoginContext = (status: boolean = false) => {
      // simulate login logic
      setLoading(true);
      setTimeout(() => {
      setIsLoggedIn(status);
      setLoading(false);
      }, 1500);
  };
  return (
      <AuthContext.Provider value={{ loading, isLoggedIn, setLoginContext }}>
      {children}
      </AuthContext.Provider>
  );
  };
Enter fullscreen mode Exit fullscreen mode
  // AuthContextType.tsx

  export interface AuthContextType {
    loading: boolean;
    isLoggedIn: boolean;
    setLoginContext: (status: boolean) => void;
  }
Enter fullscreen mode Exit fullscreen mode
  // AuthContextProviderPropType.tsx
  import React from "react";

  export interface AuthContextProviderPropType {
    children: React.ReactNode;
  }
Enter fullscreen mode Exit fullscreen mode
  // AuthContextInitialState.tsx
  import { AuthContextType } from "./AuthContextType.tsx";

  export const AuthContextInitialState: AuthContextType = {
    loading: false,
    isLoggedIn: false,
    setLoginContext: () => {},
  };
Enter fullscreen mode Exit fullscreen mode
  • The end of context setup... it's pretty straight forward stuff.

Creating Routing Files

Now it's time to create routing part. As I said before I like to keep files seperately. Let's create our routing files. In order to do that I'll create 1 directory and 3 files in it.

  • Create routing directory under the src folder.
  • In the routing folder create 3 files and name them as you wish. I'll name them; AuthorizedRoutes.tsx, UnAuthorizedRoutes.tsx and BaseRouting.tsx.
  • Let's now create the content for theses files:
  // AuthorizedRoutes.tsx
  import { RouteObject } from "react-router-dom";
  import Home from "../pages/authorized-pages/Home.tsx";

  const AuthorizedRoutes: RouteObject[] = [
    {
      path: "",
      element: <Home />,
    },
    {
      path: "home",
      element: <Home />,
    },
  ];

  export default AuthorizedRoutes;
Enter fullscreen mode Exit fullscreen mode
  // UnAuthorizedRoutes.tsx
  import { RouteObject } from "react-router-dom";
  import Login from "../pages/unauthorized-pages/Login.tsx";

  const UnAuthorizedRoutes: RouteObject[] = [
    {
      path: "",
      element: <Login />,
    },
    {
      path: "login",
      element: <Login />,
    },
  ];

  export default UnAuthorizedRoutes;
Enter fullscreen mode Exit fullscreen mode
  // BaseRouting.tsx
  import { createBrowserRouter, RouterProvider } from "react-router-dom";
  import Layout from "../components/Layout.tsx";
  import { useContext } from "react";
  import { AuthContext } from "../context/AuthContext.tsx";
  import AuthorizedRoutes from "./AuthorizedRoutes.tsx";
  import UnAuthorizedRoutes from "./UnAuthorizedRoutes.tsx";
  import ErrorComponent from "../components/ErrorComponent.tsx";

  const RoutingProvider = () => {
    const { isLoggedIn } = useContext(AuthContext);
    const router = createBrowserRouter([
      {
        path: "/",
        element: <Layout />,
        errorElement: <ErrorComponent />,
        children: isLoggedIn ? [...AuthorizedRoutes] : [...UnAuthorizedRoutes],
      },
    ]);

    return <RouterProvider router={router} />;
  };

  export default RoutingProvider;
Enter fullscreen mode Exit fullscreen mode
  • What we did? Let's review...
  • BaseRouting.tsx file is our main routing file. Inside of that we have our Layout component which is like wrapper for our app.
  • But the children of our main route is depends to the isLoggedIn state which we've created in out context part.
  • If there is a logged in user; we'll render the app with routes requires authorization, if there isn't we'll render the app with unauthorized routes.

  • This way we're also make Login route not accessible if user is logged in.

Configure Our Main.ts File

  • We need to apply those to our app:
  // main.tsx
  import ReactDOM from "react-dom/client";
  import "./index.css";
  import { AuthContextProvider } from "./context/AuthContext.tsx";
  import RoutingProvider from "./routing/BaseRouting.tsx";

  ReactDOM.createRoot(document.getElementById("root")!).render(
    <AuthContextProvider>
      <RoutingProvider />
    </AuthContextProvider>,
  );

Enter fullscreen mode Exit fullscreen mode

Conclusion

That's it. I am not exactly sure if this approach is convenient, but I am pretty sure that I'll use it in my next projects. Hope it helps you people.

Github Repo

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay