ReactJS-The Beginner Master Class
  • React In the Beginning
    • Lesson 1 - Demo: Build a Simple React App - Fast
    • Lesson 2 - HTML Review
    • Lesson 3 - CSS Review
    • Lesson 4 - Modern JavaScript (JSX) Patterns
    • Lesson 5 - Set up Dev Environment
    • Hands-on Practice
  • React Fundamentals
    • Lesson 1 - Understanding Old vs New Way of Building Web Apps - SPAs
    • Lesson 2 - Motivation for Using React as the Solution to Vanilla JS
    • Lesson 3 - What is ReactJS - How it Works
    • React Code Along from Scratch
    • Lesson 4 - Create and Run a React Project with Vite - Full Overview
    • Lesson 5 - Create Hook by State Management in React
    • Lesson 6 - React Project File and Folder Walkthrough
    • Lesson 7 - JSX and How React Treats the DOM & JSX Compilation(by Babeljs) - Overview
    • Lesson 8 - Understanding the Main Files - App.jsx and main.jsx
    • Lesson 9 - Props and One-Way Data Flow - Overview
    • Lesson 10 - Google Bookshelf App - Ver 1.0
    • Hands-on Practice I
    • Hands-on Practice II
  • React State and Styling
    • Lesson 1 - Pulling Book Data from a Different Data File
    • Lesson 2 - Overview of How State Works in React
    • Lesson 3 - RandomQuote App
    • Lesson 4 - Lifting State Up - React Pattern Overview
    • Hands-On - Simple Counter
  • Forms and Interactivity - Grocery List App
    • Lesson 1 - Setup a Simple Form and Input
    • Lesson 2 - Build Form Profile App Using Multi-input Form Data
    • Hands-on : Build a Grocery List App
  • Connecting to the Backend - Consuming APIs - UseEffect Hook
    • Lesson 1 - Connecting to the Back End - Understanding Side Effects, Hooks and useEffect - Overview
    • Lesson 2 - Fetching Data from the Backend the Right Way with useEffect Hook
    • Lesson 3 - Setting Up Loading State
    • Hands-on :Use Dependency Array and Adding Values that Control Side Effects
  • Solo Project 1
  • RESTful APIs :Build a BookSearch App -Ver 2.0
    • Lesson 1: Build and test RESTful APIs with Postman
    • Lesson 2 - BookShelf App Structure
    • Lesson 3 - Create NavBar.jsx Component
    • Lesson 4 - Create Footer Component
    • Lesson 5 - Create BookList.jsx Component
    • Lesson 6 - Create BookCard.jsx Component
    • Lesson 7 - Creating Custom Hooks - useBooks and api-client
    • Lesson 8 - Controlling Network Activities in React with AbortController
    • Lesson 9 - Show Book Details in a Modal - Working
    • Lesson 10 - Bookshelf App Summary
  • Multi-Page Applications (MPAs)
    • Build a Multi-Page React Application
    • Multi-Page React Application
    • Hands-on Practice
  • Backend Frameworks-NEXT.JS
    • Migrating from React to Next.js
    • Lesson 1: Key Concepts of NodeJS and Express for Backend Web Development
    • Lesson 2: How to set up a new Next.js project
    • Lesson 3: How to create Layouts and Pages
    • Hands-on Practice 1
    • Hands on Practice 2
      • New Project & Folder Structure
      • File-Based Routing
      • Server vs Client Components & Router Hooks
      • Start On The Navbar
      • Navbar Links, Dropdowns & React Icons
      • Active Links & Conditional Rendering
      • Homepage Components
      • Properties Page
      • Property Card Dynamic Data
      • Home Property Listings
      • Custom Not Found & Loading Pages
  • Git and GitHubs
    • Git Installation
    • Git Commands
    • GitHub Repository
    • Hands-on Practice
  • Database in Application
    • React Supabase CRUD
    • Hands-on: Note Taking App
  • NoSQL Database
    • Installing MongoDB Community Edition
    • System Env Path Setting
    • How to use MongoDB Shell
    • How to Connect and Use Mongosh in VS Code via MongoDB Extension
    • MongoDB Guide
  • Solo Project 2
  • Deployment and Web Hosting
    • Lesson 1. React+Vite+TS+Shadcn Project
    • Lesson 2. Deploying a React Vite App to Vercel from Vercel CLI
    • Lesson 3 Connecting to GitHub Repo and Automate Deployment
  • Solo Project 3
  • Final Term Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 2 Team Project
    • Level 2 Team Project
    • Level 3 Team Project
    • Level 3 Team Project
Powered by GitBook
On this page
  • Active Links & Conditional Rendering
  • 1. Implement Active Link Styling
  • 2. Implement Conditional Rendering Based on Authentication State
  • 3. Testing and Final Adjustments
  • Recap
  1. Backend Frameworks-NEXT.JS
  2. Hands on Practice 2

Active Links & Conditional Rendering

Active Links & Conditional Rendering

1. Implement Active Link Styling

a. Import the usePathname Hook

  • In your Navbar component, import the usePathname hook from Next.js’ navigation module. This hook lets you determine the current route: components/Navbar.jsx

    import { usePathname } from 'next/navigation';

b. Retrieve the Current Pathname

  • Inside your Navbar component function just below Navbar function, initialize a constant to hold the current pathname:

    const pathname = usePathname();

c. Apply Conditional Styling to Each Link

  • For each navigation link, adjust the className dynamically using a template literal and a ternary operator.

  • Example for the Home Link(/):

    <Link 
        href="/"
        className={`${pathname === '/' ? 'bg-black' : ''} px-3 py-2 text-white hover:bg-gray-900 rounded-md`}
        
        >
        Home
    </Link>
  • Example for the Properties Link(/properties):

    <Link 
       href="/properties">
       className={`${pathname === '/properties' ? 'bg-black' : ''} px-3 py-2 text-white hover:bg-gray-900 rounded-md`}
       >
       Properties
    </Link>
  • Example for the Properties Add Link(/properties/add):

    <Link 
       href="/properties/add">
       className={`${pathname === '/properties/add' ? 'bg-black' : ''} px-3 py-2 text-white hover:bg-gray-900 rounded-md`}
       >
       Add Properties
    </Link>
  • Repeat the process for all navigation links (including mobile menu links) so that the active page is highlighted (e.g., with a black background).


2. Implement Conditional Rendering Based on Authentication State

a. Set Up Authentication State

  • Since the login system isn’t fully implemented yet, use a piece of state (e.g., isLoggedIn) to simulate a user being logged in or not.

  • Import the useState hook and initialize the state:

    "use client";
    import { useState } from 'react';
    
    // Inside your component function:
    const [isLoggedIn, setIsLoggedIn] = useState(false); // Change to true to simulate a logged-in user

b. Conditionally Render Navbar Items

  • For Desktop Navigation:

    • Show “Add Property” Link Only When Logged In:

      {isLoggedIn && (
        <Link 
          href="/property/add">
          className={`${pathname === '/property/add' ? 'bg-black' : ''} px-3 py-2 text-white hover:bg-gray-900 rounded-md`}
          >
          Add Property   
        </Link>
      )}
    • Toggle Between “Login or Register” (when logged out) and Profile Dropdown (when logged in):

      {/* <!-- Right Side Menu (Logged Out) --> */}
      {!isLoggedIn ? (
        <div className="flex items-center">
          <button className="flex items-center text-white bg-gray-700 hover:bg-gray-900 rounded-md px-3 py-2">
            Login or Register
          </button>
        </div>
      ) } 
      
      {/* <!-- Right Side Menu (Logged In) --> */}
      
         {isLoggedIn && (
                  <div className="absolute inset-y-0 right-0 flex items-center pr-2 md:static md:inset-auto md:ml-6 md:pr-0">
                    <Link href="/messages" className="relative group">
                      <button
                        type="button"
                        className="relative rounded-full bg-gray-800 p-1 text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
                        <span className="absolute -inset-1.5"></span>
                        <span className="sr-only">View notifications</span>
                        <svg
                          className="h-6 w-6"
                          fill="none"
                          viewBox="0 0 24 24"
                          strokeWidth="1.5"
                          stroke="currentColor"
                          aria-hidden="true">
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"
                          />
                        </svg>
                      </button>
                      <span className="absolute top-0 right-0 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-white transform translate-x-1/2 -translate-y-1/2 bg-red-600 rounded-full">
                        {' '}
                        2
                        {/* <!-- Replace with the actual number of notifications --> */}
                      </span>
                    </Link>
                    {/* <!-- Profile dropdown button --> */}
                    <div className="relative ml-3">
                      <div>
                        <button
                          type="button"
                          className="relative flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800"
                          id="user-menu-button"
                          aria-expanded={isProfileMenuOpen}
                          aria-haspopup="true"
                          onClick={() => setIsProfileMenuOpen((prev) => !prev)}>
                          <span className="absolute -inset-1.5"></span>
                          <span className="sr-only">Open user menu</span>
                          <Image
                            className="h-8 w-8 rounded-full"
                            src={profileDefault}
                            alt=""
                          />
                        </button>
                      </div>
      
                      {/* <!-- Profile hide/show dropdown --> */}
                      {isProfileMenuOpen && (
                        <div
                          id="user-menu"
                          className=" absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
                          role="menu"
                          aria-orientation="vertical"
                          aria-labelledby="user-menu-button"
                          tabIndex="-1">
                          <Link
                            href="/profile"
                            className="block px-4 py-2 text-sm text-gray-700"
                            role="menuitem"
                            tabIndex="-1"
                            id="user-menu-item-0">
                            Your Profile
                          </Link>
                          <Link
                            href="/profiles/saved"
                            className="block px-4 py-2 text-sm text-gray-700"
                            role="menuitem"
                            tabIndex="-1"
                            id="user-menu-item-2">
                            Saved Properties
                          </Link>
                          <Link
                            href="#"
                            className="block px-4 py-2 text-sm text-gray-700"
                            role="menuitem"
                            tabIndex="-1"
                            id="user-menu-item-2">
                            Sign Out
                          </Link>
                        </div>
                      )}
                    </div>
                  </div>
                )}
  • For Mobile Navigation:

    • Apply the same conditional logic to show/hide links in the mobile menu.

    • Example:

      {/* Apply the same conditional logic to show/hide links in the mobile menu. */}
      
      {isLoggedIn ? (
        <Link 
          href="/property/add">
          className={`${pathname === '/property/add' ? 'bg-black' : ''} block rounded-md px-3 py-2 text-base font-medium`}
          >
          Add Property
          
        </Link>
      )}
      
      
      {!isLoggedIn && (
            <button className="flex items-center text-white bg-gray-700 hover:bg-gray-900 hover:text-white rounded-md px-3 py-2 my-4">
              <FaGoogle className="text-white  mr-2" />
              <span>Login or Register</span>
            </button>
      )}

3. Testing and Final Adjustments

a. Run Your Development Server

  • Start your Next.js application:

    npm run dev
  • Navigate to http://localhost:3000 and verify that:

    • The active link styling correctly highlights the current page.

    • The Navbar conditionally displays the appropriate links based on the simulated isLoggedIn state.

Result

b. Toggle the isLoggedIn State

  • Change the value of isLoggedIn (e.g., set it to true or false) and observe the changes in the Navbar for both desktop and mobile views.

c. Debug and Refine CSS Classes

  • Adjust Tailwind CSS classes as needed to achieve the desired aesthetics and responsiveness.


Recap

  • Active Link Styling: Use the usePathname hook to dynamically apply CSS classes based on the current route, ensuring that the active page is visually highlighted.

  • Conditional Rendering: Use React state (isLoggedIn) to conditionally render components like the "Add Property" link, login button, and profile dropdown. This approach sets the foundation for future authentication integration.

PreviousNavbar Links, Dropdowns & React IconsNextHomepage Components

Last updated 2 months ago