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

React组件导入Mongoose Model报错:Cannot read properties of undefined (reading 'Users')

问题描述

我尝试使用Mongoose Model从MongoDB中查询并展示用户,但将其导入profile.js组件后启动应用时,出现错误提示:

  • Cannot read properties of undefined (reading 'Users')

注:该Model在API中使用一切正常,不清楚为何在组件中会出现这种情况,此前从未遇到过该错误,求问题原因及解决方法。

相关代码

connect.js

import mongoose from "mongoose";

export default async function connect(){
    try{
        const {connection} = await mongoose.connect(process.env.MONGODB_URL)
        if(connection.readyState = 1){
            return Promise.resolve(true)
        }
    }catch(err){
        return Promise.reject(err)
    }
}

user.js(Mongoose Model)

import {Schema, models, model} from "mongoose";

const usersSchema = new Schema({
    ...
})

const Users = models.Users || model('Users', usersSchema)
export default Users

profile.js(React组件)

import { useState, useEffect } from 'react'
import {signOut, useSession} from 'next-auth/react'
import connect from "@/database/connect"
import Users from "@/database/schema/users"
export default function Profile(){
    const [loaded, setLoaded] = useState(false)
    useEffect(() => {
        setLoaded(true)
    }, [])

    const {data: session} = useSession()
    console.log(session)
    useEffect(() => {
        const userSession = session.user?.email
        if(session){
            const checkUserInfo = async() => {
                const findUser = await Users.findOne({ email: session.user?.email })
                console.log(findUser)
            } 
            checkUserInfo()  
        }
    }, [])
}
问题原因与解决方法

核心原因

  1. Mongoose不支持浏览器环境:你在客户端组件中直接调用了Mongoose Model,而Mongoose是专为Node.js后端设计的,浏览器无法运行它的底层API。
  2. 未建立数据库连接:即使忽略环境问题,你在查询前也没有调用connect()初始化数据库连接,此时models.Users会是undefined,触发Cannot read properties of undefined错误。
  3. 组件生命周期问题:你的useEffect依赖项为空数组,可能在session还未加载完成时就执行了查询逻辑,但这不是报错的根本原因。

解决方法

方案1:将查询逻辑移到API路由(通用推荐)

把数据库操作放在后端API路由中,前端组件通过fetch请求获取数据:

步骤1:创建API路由(以Next.js 13+ App Router为例)

在app/api/get-user/route.js中创建文件:

import connect from "@/database/connect";
import Users from "@/database/schema/users";

export async function GET(request) {
  await connect();
  const { searchParams } = new URL(request.url);
  const email = searchParams.get("email");

  if (!email) {
    return Response.json({ error: "缺少邮箱参数" }, { status: 400 });
  }

  const user = await Users.findOne({ email });
  return Response.json(user);
}

步骤2:修改profile.js组件调用API

import { useState, useEffect } from 'react'
import {signOut, useSession} from 'next-auth/react'

export default function Profile(){
    const {data: session} = useSession()
    const [userInfo, setUserInfo] = useState(null)

    useEffect(() => {
        async function fetchUser() {
            if (!session?.user?.email) return;
            
            const res = await fetch(`/api/get-user?email=${encodeURIComponent(session.user.email)}`)
            const user = await res.json()
            setUserInfo(user)
            console.log(user)
        }

        fetchUser()
    }, [session])

    // 渲染逻辑示例
    return (
        <div>
            {session && <p>当前用户邮箱:{session.user.email}</p>}
            {userInfo && <p>用户姓名:{userInfo.name}</p>}
        </div>
    )
}

方案2:使用服务器组件(Next.js 13+专属)

将profile.js改为服务器组件,直接在服务器端完成数据库查询:

import { getServerSession } from "next-auth/next"
import { authOptions } from "@/app/api/auth/[...nextauth]/route" // 替换为你的NextAuth配置路径
import connect from "@/database/connect"
import Users from "@/database/schema/users"

export default async function Profile(){
    const session = await getServerSession(authOptions)
    let userInfo = null

    if(session?.user?.email){
        await connect()
        userInfo = await Users.findOne({ email: session.user.email })
    }

    return (
        <div>
            {session ? (
                <>
                    <p>已登录:{session.user.email}</p>
                    {userInfo && <p>用户信息:{JSON.stringify(userInfo)}</p>}
                </>
            ) : (
                <p>未登录</p>
            )}
        </div>
    )
}

额外修复点

你的connect.js中有一个语法错误,将赋值操作=改为相等判断===:

// 原代码
if(connection.readyState = 1){
// 修改后
if(connection.readyState === 1){
    return Promise.resolve(true)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:13:17