I'm using the shadcn Navbar component on an e-commerce website.But on these links i lose data from cart.
When I use buttons for the login (/login route), register, and the logo (/home), my cart data remains saved. However, when I use that Navbar component, the cart data resets. So, I decided to add localStorage to useContext to save data immediately to localStorage. It works, but I get an error when I navigate using that Navbar, and the errors are: Error: Text content does not match server-rendered HTML. Warning: Text content did not match. Server: "0" Client: "2" Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
There is my code: Provider code:
const CartProvider = ({ children }: Children) => {
let initialCartState;
if (typeof window !== "undefined") {
const storedCart = localStorage.getItem("cart");
initialCartState = storedCart ? JSON.parse(storedCart) : defaultCartState;
} else {
initialCartState = defaultCartState;
}
const [cartState, dispatchCartAction] = useReducer(
cartReducer,
initialCartState
);
const addItemToCartHandler = (item: CartItem) => {
dispatchCartAction({ type: ActionType.ADD, item: item });
};
const removeItemFromCartHandler = (id: string) => {
dispatchCartAction({ type: ActionType.REMOVE, id: id });
};
const updateItemAmountHandler = (id: string, newAmount: number) => {
dispatchCartAction({
type: ActionType.UPDATE_VALUE,
id: id,
newAmount: newAmount,
});
};
useEffect(() => {
if (typeof window !== "undefined") {
localStorage.setItem("cart", JSON.stringify(cartState));
}
}, [cartState]);
const cartContext: CartContextStateType = {
items: cartState.items,
totalAmount: cartState.totalAmount,
addItem: addItemToCartHandler,
removeItem: removeItemFromCartHandler,
updateItemAmount: updateItemAmountHandler,
};
return (
<CartContext.Provider value={cartContext}>{children}</CartContext.Provider>
);
};
export default CartProvider;
export const useCartContext = () => useContext(CartContext);
"use client";
import * as React from "react";
import Link from "next/link";
import { cn } from "@/lib/utils";
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";
import StripeIcon from "@/app/assets/NavbarIcons/StripeIcon";
const components: { title: string; href: string; description: string }[] = [
{
title: "League of legends",
href: "/products?category=League%20of%20legends",
description:
"some descript",
},
...
...
]
const NavbarLinks = () => {
return (
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger className="bg-neutral-900">
All
</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid gap-3 p-4 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
<li className="row-span-3">
<NavigationMenuLink asChild>
<Link
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
href="/online-payments"
>
<StripeIcon className="h-24 w-24" />
<div className="mb-2 mt-4 text-lg font-medium">
Online payments
</div>
<p className="text-sm leading-tight text-muted-foreground">
descrpition
</p>
</Link>
</NavigationMenuLink>
</li>
<ListItem href="/home" title="Home">
...
</ListItem>
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger className="bg-neutral-900">
products
</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
{components.map((component) => (
<ListItem
key={component.title}
title={component.title}
href={component.href}
>
{component.description}
</ListItem>
))}
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<Link href="/special" legacyBehavior passHref>
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
Special
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
);
};