Context Navigation Styling: Sticky Prop Always False

20 Views Asked by At

I've set up a context to manage navigation, where the navigation should be styled differently depending on whether it's on the home page (no props) or not (with a prop called isSticky). However, even when it's not on the home page, the value of my isSticky prop always remains false. I'm new to using context, so any assistance would be greatly appreciated. Thanks in advance!

NavBarContext

"use client";
import React, {
  createContext,
  useState,
  useEffect,
  useLayoutEffect,
} from "react";

// Define the context interface for type safety
interface NavBarContextProps {
  isSticky: boolean;
  setIsSticky: (newState: boolean) => void;
}

// Create the context with the defined interface
export const NavBarContext = createContext<NavBarContextProps>({
  isSticky: false,
  setIsSticky: () => {},
});

// NavBarProvider component with type annotations
export const NavBarProvider = ({ children }: { children: React.ReactNode }) => {
  // Log initial state value
  const [isSticky, setIsSticky] = useState(() => {
    console.log(
      "Initial isSticky state:",
      typeof window !== "undefined"
        ? window.location.pathname !== "/"
          ? true
          : false
        : false
    );
    return typeof window !== "undefined"
      ? window.location.pathname !== "/"
        ? true
        : false
      : false; // Default to non-sticky for SSR
  });

  const handleStickyNav = () => {
    // Update state for all pages except home for initial stickiness
    if (window.location.pathname !== "/") {
      setIsSticky(true);
    } else {
      // Update state only on home page for scroll-based behavior
      if (window.scrollY > 100) {
        setIsSticky(true);
      } else {
        setIsSticky(false);
      }
    }
  };

  // Client-side update on initial render (including initial sticky state)
  useLayoutEffect(() => {
    handleStickyNav();
    console.log("isSticky after handleStickyNav (initial):", isSticky);
  }, []);

  // Update state on every navigation (client-side)
  useEffect(() => {
    const handleNavigation = () => {
      handleStickyNav();
      console.log("isSticky after handleNavigation:", isSticky);
    };

    window.addEventListener("popstate", handleNavigation); // For back/forward buttons
    return () => window.removeEventListener("popstate", handleNavigation);
  }, []);

  return (
    <NavBarContext.Provider value={{ isSticky, setIsSticky }}>
      {children}
    </NavBarContext.Provider>
  );
};

NavBar

"use client";
import React, { useContext } from "react";
import Logo from "./logo";
import NavList from "./navlist/navList";
import ResNavItem from "./navlist/resNavItem";
import NavRight from "./navlist/navRight";
import { NavBarContext } from "@/app/contexts/navBarContext";

export default function NavBar() {
  const { isSticky } = useContext(NavBarContext);

  return (
    <nav
      className={`${
        isSticky ? "bg-white" : ""
      }  fixed z-[99] w-full top-0 left-0 flex items-center justify-between py-[20px] sm:px-5xl px-md`}
    >
      <Logo sticky={isSticky} />
      <NavList sticky={isSticky} />
      <NavRight sticky={isSticky} />
      <ResNavItem sticky={isSticky} />
    </nav>
  );
}

Layout

import type { Metadata } from "next";
import { DM_Sans } from "next/font/google";
import "./globals.css";
import NavBar from "@/components/layout/navbar/navBar";
import Footer from "@/components/layout/footer/footer";
import { NavBarProvider } from "./contexts/navBarContext";

const font = DM_Sans({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Mobile Apps Development Software Company Jacksonville fl - RCK",
  description:
    "Mobile application development company in Jacksonville fl. Your's mobile apps Developement Platform run smoothly in all devices and unique Design applications Software,",
  keywords:
    "mobile apps development firm in Jacksonville,mobile apps developers in florida,mobile application development services florida,mobile application development Jacksonville,business mobile application creation in Jacksonville",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={font.className}>
        <NavBarProvider>
          <NavBar />
          <main className="flex min-h-screen flex-col items-center">
            {children}
          </main>
          <Footer />
        </NavBarProvider>
      </body>
    </html>
  );
}
0

There are 0 best solutions below