skip to Main Content

I create a navigation that will redirect the page and change the current state of the menu when clicking on the menu.

But I have the problem that when I press the ‘back/fordward navigation’ button, the menu state doesn’t change.

Can someone solve or give directions to fix the above problem.

Photos when running the application

directory structure

Code in app/test/layout.tsx file

"use client";

import Link from "next/link";
import { useState } from "react";

function classNames(...classes: any) {
  return classes.filter(Boolean).join(" ");
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const [navigation, setNavigation] = useState([
    { name: "Home", href: "/test", current: true },
    { name: "Dashboard", href: "/test/dashboard", current: false },
    { name: "Team", href: "/test/team", current: false },
    { name: "Projects", href: "/test/projects", current: false },
    { name: "Calendar", href: "/test/calendar", current: false },
  ]);

  function changeCurrent(item: any) {
    let newNav = [...navigation];
    newNav.map((nav) =>
      nav.name == item.name ? (nav.current = true) : (nav.current = false)
    );
    setNavigation(newNav);
  }

  return (
    <>
      <div className="flex">
        <div className="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
          {navigation.map((item) => (
            <Link
              key={item.name}
              href={item.href}
              className={classNames(
                item.current
                  ? "border-indigo-500 text-gray-900"
                  : "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
                "inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium"
              )}
              aria-current={item.current ? "page" : undefined}
              onClick={() => changeCurrent(item)}
            >
              {item.name}
            </Link>
          ))}
        </div>
      </div>

      <div className="m-8">{children}</div>
    </>
  );
}

I’m dealing with a problem where doing backforward history on the browser will update the current state of the menu

2

Answers


  1. Chosen as BEST ANSWER

    @Mathieu I have solved the above problem. But can you tweak my code better?

    "use client";
    
    import Link from "next/link";
    import { usePathname, useSelectedLayoutSegment } from "next/navigation";
    import { useEffect, useState } from "react";
    
    function classNames(...classes: any) {
      return classes.filter(Boolean).join(" ");
    }
    
    export default function Nav() {
      const pathname = usePathname();
      const segment = useSelectedLayoutSegment();
    
      const navigation = [
        {
          name: "Home",
          href: "/test",
          current: pathname === "/test" ? true : false,
        },
        {
          name: "Dashboard",
          href: "/test/dashboard",
          current: pathname === "/test/dashboard" ? true : false,
        },
        {
          name: "Team",
          href: "/test/team",
          current: pathname === "/test/team" ? true : false,
        },
        {
          name: "Projects",
          href: "/test/projects",
          current: pathname === "/test/projects" ? true : false,
        },
        {
          name: "Calendar",
          href: "/test/calendar",
          current: pathname === "/test/calendar" ? true : false,
        },
      ];
    
      const [navi, setNavigation] = useState(navigation);
    
      function changeCurrent(item: any) {
        let newNav = [...navigation];
        newNav.map((nav) =>
          nav.name == item.name ? (nav.current = true) : (nav.current = false)
        );
        setNavigation(newNav);
      }
    
      return (
        <div className="flex">
          <div className="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
            {navigation.map((item) => (
              <Link
                key={item.name}
                href={item.href}
                className={classNames(
                  item.current
                    ? "border-indigo-500 text-gray-900"
                    : "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
                  "inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium"
                )}
                aria-current={item.current ? "page" : undefined}
                onClick={() => {
                  changeCurrent(item);
                }}
              >
                {item.name}
              </Link>
            ))}
          </div>
        </div>
      );
    }
    

  2. With nextJS, you can use router to get pathname and use it to init current boolean flags based on your url in your navigation state array.

    This will allow to have good state when loading page from a direct url (eg. /test/dashboard) or using prev/next button of the web browser.

    More information on how to use router here: Get URL pathname in nextjs or https://beta.nextjs.org/docs/api-reference/use-router

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search