next.js 如何解决在组件中使用“useClient”时出现“Maximum Call Stack Exceeded”错误?

yrwegjxp  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(80)

我正在开发一个Next.js应用程序,当我尝试在一个组件中使用useClient钩子时遇到了一个问题。每当我在组件中包含useClient时,我都会收到一个“Maximum call stack exceeded”错误,这似乎表明某种形式的递归或无限循环。

"use client"
import { serverPropsWithMembers } from "@/types"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { ChevronDown, LogOut, PlusCircle, Settings, Trash, UserPlus, Users } from 'lucide-react'
import { Role } from "@/Models/schema-models"
import { useModel } from "@/app/hooks/use-model-store"

interface serverHeaderProps{
    server:serverPropsWithMembers,
    role?:Role
}
const ServerHeader = ({
    server,
    role
}:serverHeaderProps) => {
  const { onOpen  } = useModel()

  const isAdmin = role === Role.ADMIN
  const isModerator = isAdmin || role === Role.MODERATOR
  
 
  
  return (
    <DropdownMenu>
    <DropdownMenuTrigger className="focus:outline-none" asChild>
      <button className="h-12 w-full text-md px-3 font-semibold bg-neutral-200 dark:bg-neutral-800 hover:bg-zinc-900/10 dark:hover:bg-zinc-900/50 flex items-center border-b-2">
        {server.name}
        <ChevronDown className="h-5 w-5 ml-auto"/>
      </button>
    </DropdownMenuTrigger>
    <DropdownMenuContent className="text-xs font-medium w-56 items-center text-black space-y-[2px] dark:text-neutral-400 ">
      {isModerator && (
      <DropdownMenuItem 
      onClick={()=> onOpen('invite',{server})}
      className="px-3 py-2 text-sm cursor-pointer">
        Invite People
        <UserPlus className='h-4 w-5 ml-auto'/>
      </DropdownMenuItem>
      )}
      {isAdmin && (
      <DropdownMenuItem className=" px-3 py-2 text-sm cursor-pointer">
        Server settings 
        <Settings className='h-4 w-4 ml-auto'/>
      </DropdownMenuItem>
      )}
      {isAdmin && (
      <DropdownMenuItem className=" px-3 py-2 text-sm cursor-pointer">
        Manage Members
        <Users className='h-4 w-4 ml-auto'/>
      </DropdownMenuItem>
      )}
      {isAdmin && (
      <DropdownMenuItem className=" px-3 py-2 text-sm cursor-pointer">
         create Channel
        <PlusCircle className='h-4 w-4 ml-auto'/>
      </DropdownMenuItem>
      )}
      {isModerator && (
      <DropdownMenuItem className="px-3 py-2 text-sm cursor-pointer">
        <DropdownMenuSeparator className='dark:bg-zinc-600 w-full rounded-md'/>
      </DropdownMenuItem>
      )}
       {isAdmin && (
      <DropdownMenuItem className="text-rose-500 px-3 py-2 text-sm cursor-pointer">
         Delete Server
        <Trash className='h-4 w-4 ml-auto '/>
      </DropdownMenuItem>
      )}
       {!isAdmin && (
      <DropdownMenuItem className="text-rose-500 px-3 py-2 text-sm cursor-pointer">
         Leave Server
        <LogOut className='h-4 w-4 ml-auto '/>
      </DropdownMenuItem>
      )}

    </DropdownMenuContent>
  </DropdownMenu>
  
  )
}

export default ServerHeader

字符串
当我没有使用“use client”时,错误会发生。但是由于useModel Hook,我需要“use client”。所以有人知道我如何在下一个js文件中修复这个问题吗?我还检查了所有的依赖项,没有任何依赖项之间的冲突会导致递归。下面是hook文件:

import { create } from 'zustand'
import { Server } from '@/Models/schema-models';
import { serverPropsWithMembers } from '@/types';

export type ModelType = "createServer" | "invite" 

interface ModelData {
   server?:serverPropsWithMembers
}

interface ModelStore {
    type: ModelType | null;
    data:ModelData;
    isOpen: boolean;
    onOpen: (type:ModelType,data?: ModelData) => void;
    onClose: () => void;
}

export const useModel = create<ModelStore>((set)=>({
    type :null,
    data:{},
    isOpen:false,
    onOpen:(type,data={}) => set({isOpen:true,type,data}),
    onClose:() => set({isOpen:false,type:null})
}))


下面是serverWithMembers类型文件:

import { IMember, IServer, IUser } from "./Models/schema-models"

export type serverPropsWithMembers = IServer & {
members:IMember & {
  UserProfile : IUser
}}


这是架构文件

import mongoose, { Schema, Types, model, models } from 'mongoose';

export interface IUser {
userId:string,
name:string,
email:string,
imageUrl:string,
server:Types.ObjectId[],
members:Types.ObjectId[],
channels:Types.ObjectId[]
}

const UserProfileSchema = new Schema<IUser>({
    userId: { type: String, unique: true },
    name: String,
    email: {type:String,index:true , unique:true},
    imageUrl: {type: String,index:true},
    
    server:[{type:Schema.Types.ObjectId,ref:'Server'}],
    members:[{type:Schema.Types.ObjectId,ref:'Members'}],
    channels:[{type:Schema.Types.ObjectId,ref:'Channels'}]
}, {
    timestamps: true
});

const UserProfile  = models?.['UserProfile'] || model<IUser>('UserProfile', UserProfileSchema);




export interface IServer {
name:string,
imageUrl:string,
inviteCode:string,
profileId:Types.ObjectId,
channels:Types.ObjectId[],
members:Types.ObjectId[]
}

const serverSchema = new Schema<IServer>({
    name: String,
    imageUrl: { type: String, index: true },
    inviteCode: { type: String, unique: true },

    profileId: { type: Schema.Types.ObjectId, ref: 'UserProfile', index: true },
    channels:[{type: Schema.Types.ObjectId,ref:'Channels'}],
    members:[{type: Schema.Types.ObjectId,ref:'Members'}],
    
},{
    timestamps:true
});

const Server = models?.['Server'] || model<IServer>('Server', serverSchema);


export interface IMember {
    role: Role;
    profileId: Types.ObjectId;
    servers: Types.ObjectId[];
  }
  
  export enum Role {
    ADMIN = 'ADMIN',
    MODERATOR = 'MODERATOR',
    GUEST = 'GUEST',
  }
  
  const MemberSchema = new Schema<IMember>({
    role: { type: String, default: Role.GUEST, enum: Object.values(Role), index: true },
    profileId: { type: Schema.Types.ObjectId, ref: 'User', index: true },
    servers: [{ type: Schema.Types.ObjectId, ref: 'Server' }],
  }, {
    timestamps: true,
  });
  
const Members = models?.['Members'] ||  model<IMember>("Members",MemberSchema)



export interface IChannel {
    name:string,
    type:ChannelType,
    profileId:Types.ObjectId,
    server:Types.ObjectId[]
}

 export enum ChannelType {
    TEXT = 'TEXT',
    VIDEO = 'VIDEO',
    AUDIO = 'AUDIO'
}

const ChannelSchema  = new Schema<IChannel>({
    name:String,
    type:{ type: String , default:ChannelType.TEXT,required:true,enum:Object.values(ChannelType),index:true},

    profileId: { type: Schema.Types.ObjectId, ref: 'UserProfile', index: true },
    server:[{type: Schema.Types.ObjectId,ref:'Server'}]
},{
    timestamps:true
})

const Channels = models?.['Channels']||  model<IChannel>("Channels",ChannelSchema)



export { UserProfile, Server , Members , Channels };

wqnecbli

wqnecbli1#

可能的修复方法:我也遇到过类似的问题,当我将从MongoDB检索到的数据传递给另一个组件的prop时,出现了“Maximum Call Stack Exceeded”错误。但是,当我传递我在代码中定义的“mock data”而不是从数据库中检索时,错误消失了。
发生错误是因为我试图传递包含MongoDB-given _id的'comment'对象。一旦我'清理'数据并删除传递给其他组件的prop的'comment'对象中包含的_id,然后错误就被修复了。
我的解释有许多术语是我的代码所独有的,但我希望它可以帮助将来遇到这个错误的其他人-因为“超过最大调用堆栈”错误确实没有说明实际错误是什么,我仍然不知道为什么这是显示的特定错误。
我从这个故事中得到的教训是:**清理/检查你的数据。

相关问题