Next.js Discord

Discord Forum

Sidebar resets on route change

Unanswered
Dwarf Crocodile posted this in #help-forum
Open in Discord
Dwarf CrocodileOP
This is my folder structure:

/app
/(dashboard)
/components
/templates
/intro
layout.tsx


I have a Sidebar in this layout.tsx which has few Groups (collapsible) and sub groups.
By default, all the groups in sidebar are in expanded state.

If I collapse any group, and go to any other route (which fall under this layout.tsx), all the groups expand again.
That means my sidebar is getting re-rendered, but how?

2 Replies

Dwarf CrocodileOP
Sidebar.tsx:

import { cn } from "@/lib/utils";
import { ScrollArea } from "@/components/ui/scroll-area";
import NavigationGroup from "../ui/NavigationGroup";
import NavigationLink from "../ui/NavigationLink";
import { ChevronRight,....} from "lucide-react";
import { sidebarNavigation } from "@/constants";

interface SidebarProps {
  className?: string;
}

export default function Sidebar({ className }: SidebarProps) {
  return (
    <aside
      className={cn(
        "top-14 z-30 -ml-2 h-[calc(100vh-5rem)] w-full shrink-0 hidden lg:sticky lg:block lg:self-start bg-black/10",
        "md:translate-x-0",
        className
      )}
    >
      <ScrollArea className="relative overflow-hidden h-full py-6 pr-6 lg:py-8">
        <div className="w-full">
          <div className="pb-4">
            {sidebarNavigation.map(({ icon: Icon, group, items }, key) => (
              <NavigationGroup
                key={key}
                icon={<Icon className="h-4 w-4" />}
                group={group}
              >
                {items.map(({ title, href, tags }, key) => (
                  <NavigationLink key={key} href={href} tags={tags}>
                    {title}
                  </NavigationLink>
                ))}
              </NavigationGroup>
            ))}
          </div>
        </div>
      </ScrollArea>
    </aside>
  );
}
NavigationGroup.tsx:

"use client";
import { useState } from "react";
import { ChevronRight } from "lucide-react";
import { cn } from "@/lib/utils";

interface NavigationGroupProps {
  group: string;
  children: React.ReactNode;
  icon?: React.ReactNode;
  defaultOpen?: boolean;
}

export default function NavigationGroup({
  group,
  children,
  icon,
  defaultOpen = true,
}: NavigationGroupProps) {
  const [isOpen, setIsOpen] = useState(defaultOpen);

  return (
    <div className="space-y-1">
      <button
        onClick={() => setIsOpen(!isOpen)}
        className={cn(
          "flex w-full items-center justify-between rounded-md px-2 py-2 text-sm font-semibold",
          "hover:bg-[#1e1e1e] text-white"
        )}
      >
        <div className="flex items-center gap-2">
          {/* {icon} */}
          <span>{group}</span>
        </div>
        <ChevronRight
          className={cn(
            "h-4 w-4 transition-transform duration-200",
            isOpen && "rotate-90"
          )}
        />
      </button>
      {isOpen && <div className="ml-4 pb-2">{children}</div>}
    </div>
  );
}