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

NextJS出现Maximum call stack size exceeded错误,求解决及实现点赞功能

修复NextJS点赞/取消点赞功能的RangeError及逻辑问题

问题分析

出现RangeError: Maximum call stack size exceeded通常是因为无限循环渲染或对象循环引用。结合你的代码,核心问题包括:

  • 点赞/取消点赞逻辑颠倒:点击"Liked"按钮时固定传true,导致重复添加用户ID,无法触发取消操作
  • 未根据当前点赞状态动态切换按钮UI与处理逻辑
  • 可能因API响应存在循环引用,导致JSON.parse或console.log时触发栈溢出

修复步骤

1. 动态判断用户点赞状态

在组件内实时计算当前用户是否已点赞,替代固定传参:

const hasLiked = likesArr.includes(user);

2. 修正handleLike逻辑

根据hasLiked状态决定操作类型,同时使用函数式更新确保状态基于最新值:

  • 已点赞时:调用接口取消点赞,从数组移除用户ID
  • 未点赞时:调用接口添加点赞,向数组添加用户ID

3. 避免循环引用问题

确保API返回的响应无循环引用,或简化响应日志输出(仅打印关键状态,而非整个响应对象)

4. 动态切换按钮UI

根据hasLiked状态自动切换图标和文字(已点赞/未点赞)

完整修复代码

'use client'
import { useState } from "react";
import { FaRegComment } from "react-icons/fa";
import { PiShareFatThin } from "react-icons/pi";
import { AiOutlineLike, AiFillLike } from "react-icons/ai";

const PostReactions = ({ postReactions = [], postComments = [], postShares = [] }) => {
  const [user, setUser] = useState('66236aac5820fcac4e235f0c');
  // 从props初始化点赞数组:提取已点赞用户ID
  const [likesArr, setLikesArr] = useState(postReactions.map(reaction => reaction.createdBy));

  // 判断当前用户是否已点赞
  const hasLiked = likesArr.includes(user);

  const handleLike = async () => {
    const postId = '663f2de2d1bbf549ac7fbabe';
    const shouldAddLike = {
      postId,
      userId: user,
      likeType: 'like',
      isReacted: !hasLiked, // 反转当前状态:未点赞则添加,已点赞则取消
    };

    try {
      const response = await fetch(`/api/like`, {
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        method: "POST",
        body: JSON.stringify(shouldAddLike),
      });
      const parse = await response.json();
      // 简化日志输出,避免循环引用导致栈溢出
      console.log('点赞操作结果:', parse.success ? '成功' : '失败');

      // 函数式更新确保状态基于最新值
      setLikesArr(prevArr => {
        if (hasLiked) {
          return prevArr.filter(id => id !== user);
        } else {
          return [...prevArr, user];
        }
      });
    } catch (error) {
      console.error("更新点赞状态失败:", error);
    }
  }

  return (
    <div className="w-full md:w-2/3 flex-between py-2 font-poppins ">
      <div className="flex-center space-x-1 md:space-x-2 cursor-pointer" onClick={handleLike}>
        {/* 根据点赞状态切换图标 */}
        {hasLiked ? <AiFillLike className={`w-5 h-5`} /> : <AiOutlineLike className={`w-5 h-5`} />}
        {/* 根据点赞状态切换文字 */}
        <p className="base-semibold">{hasLiked ? 'Liked' : 'Like'}</p>
      </div>
      <div className="flex-center space-x-1 md:space-x-2 cursor-pointer">
        <FaRegComment className={`w-5 h-5`} />
        <p className="base-semibold">Comment</p>
      </div>
      <div className="flex-center space-x-1 md:space-x-2 cursor-pointer">
        <PiShareFatThin className={`w-5 h-5`} />
        <p className="base-semibold">Share</p>
      </div>
    </div>
  );
}

export default PostReactions;

额外注意事项

  • 确保/api/like接口正确处理isReacted参数:true执行添加点赞,false执行取消点赞
  • 若API返回的响应对象存在循环引用,需在后端序列化时排除循环字段,或前端仅打印必要状态字段
  • 函数式更新(setLikesArr(prevArr => ...))可避免闭包导致的状态更新滞后问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 20:44:52