我正在开发 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 };
@AbdullahDeveloper @Artūrs Laizāns 嗨,你们能解决这个问题吗?谢谢!