如何解决在组件中使用“useClient”时出现“超出最大调用堆栈”错误?

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

我正在开发 Next.js 应用程序,在尝试在我的组件之一中使用 useClient 挂钩时遇到问题。每当我在组件中包含 useClient 时,我都会收到“超出最大调用堆栈”错误,这似乎表明某种形式的递归或无限循环。

    "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 文件中解决这个问题?我还检查了所有依赖项,依赖项之间没有任何可能导致递归的冲突。 这是挂钩文件:

  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 };
typescript next.js error-handling infinite-loop
1个回答
0
投票

@AbdullahDeveloper @Artūrs Laizāns 嗨,你们能解决这个问题吗?谢谢!

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