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

Next.js 14竞价系统报错:TypeError: mongoose.models未定义

解决Next.js 14中Mongoose models 未定义的错误

问题根源

这个错误主要来自三个点:

  1. 数据库连接是异步操作,你直接调用connect()后没等连接完成就加载模型、执行查询,此时mongoose.models还没初始化
  2. Next.js 14服务器组件的执行流程里,全局mongoose.models对象可能还没挂载就被访问
  3. 如果Form是客户端组件(带'use client'指令),在里面导入Bid模型会导致Mongoose在浏览器环境运行——而Mongoose只支持Node.js环境

修复步骤

1. 先确保数据库连接完成再操作

修改你的页面组件,把connect()改成异步等待,避免连接未就绪就执行查询:

import React from "react";
import Item from "@/models/Item";
import Form from "./Form";
import { GetDataFromToken } from "@/helpers/GetDataFromToken";
import { connect } from "@/helpers/DBConfig";

const page = async ({ params }) => {
  // 必须等连接完成再继续
  await connect();
  
  const { slug } = params;
  const item = await Item.findOne({ _id: slug });
  const user = GetDataFromToken();

  return (
    <div>
      <h1>{item?.name}</h1>
      <p>{item?.description}</p>
      <p>Starting bid: {item?.startingPrice}</p>
      <Form user={user.id} item={item._id} />
    </div>
  );
};

export default page;

同时把DBConfig里的连接函数改成异步并增加状态判断:

// @/helpers/DBConfig.js
import mongoose from "mongoose";

export async function connect() {
  // 如果已经连接,直接返回
  if (mongoose.connections[0].readyState) return;

  try {
    await mongoose.connect(process.env.MONGODB_URI);
  } catch (error) {
    throw new Error("数据库连接失败:" + error.message);
  }
}

2. 调整Bid模型的初始化逻辑

把模型判断改成基于connection.models的方式,避免访问未初始化的全局models:

import mongoose from "mongoose";

const bidSchema = new mongoose.Schema(
  {
    bidder: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
    item: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Item",
      required: true,
    },
    price: {
      type: Number,
      required: true,
    },
  },
  { timestamps: true }
);

// 改用connection.models检查,更可靠
const Bid = mongoose.connection.models.Bid || mongoose.model("Bid", bidSchema);

export default Bid;

3. 客户端组件不能用Mongoose

如果你的Form是客户端组件(带'use client'),绝对不能在里面导入Bid模型。所有竞价提交的逻辑要放到API路由里:

创建app/api/bids/route.js处理提交:

import { connect } from "@/helpers/DBConfig";
import Bid from "@/models/Bid";
import { NextResponse } from "next/server";

export async function POST(req) {
  await connect();
  const { bidder, item, price } = await req.json();

  try {
    const newBid = new Bid({ bidder, item, price });
    await newBid.save();
    return NextResponse.json({ success: true, bid: newBid });
  } catch (error) {
    return NextResponse.json({ success: false, error: error.message }, { status: 500 });
  }
}

然后在Form组件里用fetch调用这个API:

// Form.jsx(客户端组件)
'use client';

import { useState } from 'react';

export default function Form({ user, item }) {
  const [price, setPrice] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    const res = await fetch('/api/bids', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ bidder: user, item, price: Number(price) })
    });
    const data = await res.json();
    if (data.success) {
      alert('竞价提交成功');
      setPrice('');
    } else {
      alert('提交失败:' + data.error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="number"
        value={price}
        onChange={(e) => setPrice(e.target.value)}
        placeholder="输入竞价金额"
        required
      />
      <button type="submit">提交竞价</button>
    </form>
  );
}

额外提醒

所有涉及Mongoose的代码(模型导入、数据库操作)都只能放在服务器组件或API路由里,别在客户端组件里碰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:43:10