You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13.4点赞按钮开发遇Maximum call stack size exceeded错误求助

Next.js 13.4 点赞按钮栈溢出错误解决

我是一名初级开发者,正在使用Next.js 13.4开发点赞按钮功能,希望点击按钮时实现点赞数递增,但出现如下错误:

Error: Maximum call stack size exceeded

相关代码如下:

"use client"
import { formatDateString } from "@/lib/utils";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import DeleteBuzzWeft from "../forms/DeleteBuzzWeft";

interface Props {
  id: string,
  currentUserId: string,
  parentId: string | null,
  content: string,
  author: {
    name: string;
    image: string;
    id: string;
  },
  community: {
    id: string;
    name: string;
    image: string;
  } | null;
  createdAt: string;
  comments: {
    author: {
      image: string;
    }
  }[]
  isComment?: boolean;
}

const BuzzWeftCard = ({ id, currentUserId, parentId, content, author, community, createdAt, comments, isComment }: Props) => {
  const [ randomLikes, setRandomLikes] = useState(0);

  useEffect(() => {
    setRandomLikes(Math.floor(Math.random() * 1000));
  }, []);

  return (
    <article className={`flex w-full flex-col rounded-xl ${isComment ? 'px-0 xs:px-7' : 'bg-dark-2 p-7'}`}>

      <div className="flex items-start justify-between">
        <div className="flex w-full flex-1 flex-row gap-4">
          <div className="flex flex-col items-center">
           
            <div className="buzz-card_bar" />
          </div>
          <div className="flex w-full flex-col">
            <p className="mt-2 text-small-regular text-light-1">{content}</p>
            <div className={`${isComment && 'mb-10'} mt-5 flex flex-col gap-3`}>
              <div className="flex gap-3.5">
                <Link href={`/`}>
                  <Image src='/assets/heart-gray.svg' alt="heart" width={24} height={24} className="cursor-pointer object-contain" />
                </Link>
                {/* <div className=""> */}
                  {/* <Link href={`/buzz/${id}`}> */}
                    <Image src='/assets/reply.svg' alt="reply" width={24} height={24} className="cursor-pointer object-contain" />
                    <p className=" text-x-small-semibold">{randomLikes}</p>
                  {/* </Link> */}
                {/* </div> */}
              </div>
            </div>
          </div>
        </div>

      </div>
    </article>
  )
}

export default BuzzWeftCard

错误原因

出现栈溢出的核心原因是点赞按钮的点击事件处理逻辑错误,常见场景包括:

  • 直接在onClick中执行setRandomLikes(randomLikes + 1)而非包裹在函数内,导致组件渲染时立即调用setState触发重渲染,重渲染又再次执行setState,形成无限循环耗尽调用栈。
  • 使用非函数式更新状态,闭包捕获旧状态值引发异常更新逻辑。

解决方案

  1. 定义点赞处理函数,使用函数式更新获取最新状态值,避免闭包问题:
    const handleLike = () => {
      setRandomLikes(prevLikes => prevLikes + 1);
    };
    
  2. 修改点赞按钮代码,移除不必要的跳转Link(若仅需点赞无需跳转),并绑定点击事件:
    <div onClick={handleLike} className="cursor-pointer">
      <Image src='/assets/heart-gray.svg' alt="heart" width={24} height={24} className="object-contain" />
    </div>
    
  3. 当前代码中useEffect为空依赖仅初始化点赞数,逻辑正确无需修改。

修改后的完整代码

"use client"
import { formatDateString } from "@/lib/utils";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import DeleteBuzzWeft from "../forms/DeleteBuzzWeft";

interface Props {
  id: string,
  currentUserId: string,
  parentId: string | null,
  content: string,
  author: {
    name: string;
    image: string;
    id: string;
  },
  community: {
    id: string;
    name: string;
    image: string;
  } | null;
  createdAt: string;
  comments: {
    author: {
      image: string;
    }
  }[]
  isComment?: boolean;
}

const BuzzWeftCard = ({ id, currentUserId, parentId, content, author, community, createdAt, comments, isComment }: Props) => {
  const [ randomLikes, setRandomLikes] = useState(0);

  useEffect(() => {
    setRandomLikes(Math.floor(Math.random() * 1000));
  }, []);

  // 点赞处理函数
  const handleLike = () => {
    setRandomLikes(prevLikes => prevLikes + 1);
  };

  return (
    <article className={`flex w-full flex-col rounded-xl ${isComment ? 'px-0 xs:px-7' : 'bg-dark-2 p-7'}`}>

      <div className="flex items-start justify-between">
        <div className="flex w-full flex-1 flex-row gap-4">
          <div className="flex flex-col items-center">
            <div className="buzz-card_bar" />
          </div>
          <div className="flex w-full flex-col">
            <p className="mt-2 text-small-regular text-light-1">{content}</p>
            <div className={`${isComment && 'mb-10'} mt-5 flex flex-col gap-3`}>
              <div className="flex gap-3.5 items-center">
                {/* 移除跳转Link,改为点击点赞 */}
                <div onClick={handleLike} className="cursor-pointer">
                  <Image src='/assets/heart-gray.svg' alt="heart" width={24} height={24} className="object-contain" />
                </div>
                <div className="cursor-pointer">
                  <Image src='/assets/reply.svg' alt="reply" width={24} height={24} className="object-contain" />
                </div>
                <p className="text-x-small-semibold">{randomLikes}</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </article>
  )
}

export default BuzzWeftCard

内容的提问来源于stack exchange,提问作者Anas Isah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 21:14:51