所以我已经有一段时间遇到“⨯内部错误:范围错误:超出最大调用堆栈大小”,我似乎无法弄清楚是什么原因造成的。我试图做到这一点,以便当单击“添加到购物车”按钮时,它会将购物车中的商品数量增加 1。
我正在使用 Typescript 和 Nextjs
这是我的页面.tsx:
"use client";
import React from "react";
import { BackgroundGradient } from "../components/ui/background-gradient";
import Image from "next/image";
import NavBar from "../components/NavBar";
import FetchData from "../FetchData";
import { useState, useEffect } from 'react';
interface ShopProps {
onCount: number;
onItemPress: (count: number) => void;
}
const Shop: React.FC<ShopProps> = ({ onCount, onItemPress }) => {
interface Product {
id: number;
title: string;
description: string;
price: number;
image: string;
}
const [productData, setProductData] = useState<Product[] | null>(null);
let count = 0;
return (
<>
<FetchData onDataReceived={setProductData}>
{null}
</FetchData>
<NavBar />
<div className="rounded-[22px] max-w-sm pt-20">
{
productData && (
<ul>
{productData.map((product: Product) => (
<BackgroundGradient className="rounded-[22px] max-w-sm p-4 sm:p-10 bg-white dark:bg-zinc-900" key={count}>
<li key={product.id}>
<Image
src={product.image}
alt={product.title}
width="400"
height="400"
className="object-contain"
/>
<p className="text-base sm:text-xl text-black mt-4 mb-2 dark:text-neutral-200">{product.title}</p>
<p className="text-sm text-neutral-600 dark:text-neutral-400">{product.description}</p>
<div className="flex items-center space-x-2">
<button className="rounded-full pl-4 pr-1 py-1 text-white flex items-center space-x-1 bg-black mt-4 text-xs font-bold dark:bg-zinc-800">
<span>Buy now </span>
<span className="bg-zinc-700 rounded-full text-[0.6rem] px-2 py-0 text-white">
${product.price}
</span>
</button>
<button
onClick={() => {
onItemPress(onCount + 1);
}}
className="rounded-full pl-4 pr-4 py-1 text-white flex items-center
justify-center space-x-1 bg-black mt-4 text-xs font-bold dark:bg-zinc-800"
>
Add to Cart
</button>
</div>
</li>
</BackgroundGradient>
))}
</ul>
)
}
<BackgroundGradient className="rounded-[22px] max-w-sm p-4 sm:p-10 bg-white dark:bg-zinc-900">
<Image
src='/og-package-react'
alt="jordans"
height="400"
width="400"
className="object-contain"
/>
<p className="text-base sm:text-xl text-black mt-4 mb-2 dark:text-neutral-200">
Air Jordan 4 Retro Reimagined
</p>
<p className="text-sm text-neutral-600 dark:text-neutral-400">
The Air Jordan 4 Retro Reimagined Bred will release on Saturday,
February 17, 2024. Your best opportunity to get these right now is by
entering raffles and waiting for the official releases.
</p>
<button className="rounded-full pl-4 pr-1 py-1 text-white flex items-center space-x-1 bg-black mt-4 text-xs font-bold dark:bg-zinc-800">
<span>Buy now </span>
<span className="bg-zinc-700 rounded-full text-[0.6rem] px-2 py-0 text-white">
$100
</span>
</button>
</BackgroundGradient>
</div>
</>
);
}
export default Shop;
购物车.tsx
"use client";
import React from "react";
import Badge from "@material-ui/core/Badge";
import { useState } from 'react';
import ShoppingCartIcon from "@material-ui/icons/ShoppingCart";
import Shop from "../shop/page";
export default function ShoppingCart() {
const [itemCount, setItemCount] = useState(0);
const handleItemPress = (newCount: number) => {
setItemCount(newCount);
};
return (
<div>
<div>
<Badge color="secondary" badgeContent={itemCount} overlap="rectangular">
<ShoppingCartIcon />
</Badge>
</div>
<Shop onCount={itemCount} onItemPress={handleItemPress} />
</div>
);
}
导航栏.tsx
"use client";
import React from "react";
import { HoveredLink, Menu, MenuItem, ProductItem } from "./ui/navbar-menu";
import { cn } from "@/app/utils/cn";
import ShoppingCart from "./ShoppingCart";
import { useState } from 'react';
export default function NavbarDemo() {
return (
<div className="relative w-full flex items-center justify-center">
<Navbar className="top-2" />
<p className="text-black dark:text-white">
The Navbar will show on top of the page
</p>
</div>
);
}
function Navbar({ className }: { className?: string }) {
const [activeItem, setActiveItem] = useState<string | null>(null);
return (
<div className={cn("fixed top-10 inset-x-0 max-w-2xl mx-auto z-50", className)}>
<Menu setActive={setActiveItem}>
<a className="text-white" href="/">Home</a>
<a className="text-white" href="/shop">Shop</a>
</Menu>
<ShoppingCart />
</div>
);
}
获取数据.tsx
import { useEffect, useState, ReactNode } from 'react';
interface FetchDataProps {
children: ReactNode;
onDataReceived?: (data: any) => void;
}
const FetchData = ({ children, onDataReceived }: FetchDataProps) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://fakestoreapi.com/products?limit=5', {mode: "cors"})
.then((res) => {
if (res.status >= 400) {
throw new Error("server error");
}
return res.json();
})
.then((fetchedData) => {
setData(fetchedData);
if(onDataReceived) {
onDataReceived(fetchedData);
}
})
.catch((error) => setError(error))
.finally(() => setLoading(false));
}, [onDataReceived]);
return children;
};
export default FetchData;
我试图做到这一点,以便当单击“添加到购物车”按钮时,购物车中的商品数量会增加 1。
您的组件层次结构中存在循环渲染。
<Shop />
=> <> ... <Navbar /> </>
=> <> ... <ShoppingCart /> </>
=> <> ... <Shop /> </>
=> <> ... <Navbar /> </> // again
=> ... infinite loop.
让我们尝试从商店组件中删除“导航栏”,您将看到循环将结束。