内部错误:RangeError:超出最大调用堆栈大小 Next.js React

问题描述 投票:0回答:1

所以我已经有一段时间遇到“⨯内部错误:范围错误:超出最大调用堆栈大小”,我似乎无法弄清楚是什么原因造成的。我试图做到这一点,以便当单击“添加到购物车”按钮时,它会将购物车中的商品数量增加 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。

reactjs typescript next.js
1个回答
0
投票

您的组件层次结构中存在循环渲染。

<Shop /> 
=> <> ... <Navbar /> </> 
=> <> ... <ShoppingCart /> </>
=> <> ... <Shop /> </>
=> <> ... <Navbar /> </>  // again 
=> ... infinite loop.

让我们尝试从商店组件中删除“导航栏”,您将看到循环将结束。

© www.soinside.com 2019 - 2024. All rights reserved.