Next.js 14.2中MongoDB findOneAndUpdate无法正常工作的问题
解决Next.js 14.2中MongoDB更新comment字段的错误
问题背景
使用Next.js 14.2修改MongoDB的comment字段时,遇到两个核心错误:
- 调用
connectDB()时,报错:Error connecting to MongoDB: TypeError: Cannot read properties of undefined (reading '0') - 不调用
connectDB()时,报错:TypeError: _mongodb_proposalSchema__WEBPACK_IMPORTED_MODULE_2__.default.findOneAndUpdate is not a function
另外,相同代码复制到单独目录用npx ts-node index.ts运行完全正常。
相关代码
服务端操作函数(addAComment)
export async function addAComment(proposalId: number, newComment: string) { const updateFields: any = {}; updateFields.comment = newComment; console.log("here is a new comment:", newComment); const result = await ProposalModel.findOneAndUpdate( { proposalId: proposalId }, { $set: updateFields }, { new: true } ); console.log("comment added, this is resut:", result); }
connectDB代码
import mongoose from "mongoose"; const connectDB = async () => { try { if (mongoose.connections[0].readyState) { console.log("Already connected to MongoDB"); return; } await mongoose.connect(process.env.MONGODB_URI as string, { //serverSelectionTimeoutMS: 70000, }); console.log("Connected to MongoDB"); } catch (error) { console.error("Error connecting to MongoDB:", error); throw error; } }; export default connectDB;
前端处理逻辑
const [comment, setComment] = useState(""); const handleSendTransaction = async () => { if (comment.length) { await addAComment(proposalId, comment); } }; .... <button onClick={handleSendTransaction}> Send Transaction </button>
Schema定义
import { Document, Model, Schema, model, models } from "mongoose"; interface IProposalDocument extends Document { proposalId: number; toCompanyAddress: string; fromAddress: string; proposalURI: string; decisionStatus: number; fundingGoal: string; currentFunding: string; deadline: string; comment?: string; } const proposalSchema: Schema<IProposalDocument> = new Schema( { proposalId: { type: Number, required: true, unique: true, }, toCompanyAddress: { type: String, required: true, }, fromAddress: { type: String, required: true, }, proposalURI: { type: String, required: true, }, decisionStatus: { type: Number, required: true, }, fundingGoal: { type: String, required: true, }, currentFunding: { type: String, required: true, }, deadline: { type: String, required: true, }, comment: { type: String, default: "", }, }, { timestamps: true } ); const ProposalModel: Model<IProposalDocument> = models?.proposals || model<IProposalDocument>("proposals", proposalSchema);
解决方案
1. 修复connectDB的连接状态判断逻辑
原代码直接访问mongoose.connections[0],当连接未初始化时connections为空数组,导致读取[0]报错。修改为更可靠的判断方式:
const connectDB = async () => { try { // 直接检查当前连接的就绪状态 const isConnected = mongoose.connection.readyState === 1; if (isConnected) { console.log("Already connected to MongoDB"); return; } await mongoose.connect(process.env.MONGODB_URI as string); console.log("Connected to MongoDB"); } catch (error) { console.error("Error connecting to MongoDB:", error); throw error; } };
2. 把数据库操作移到API路由(核心修复)
Next.js客户端组件无法直接运行mongoose代码,必须通过API路由或Server Component处理数据库请求。
步骤1:创建API路由文件app/api/add-comment/route.ts
import connectDB from "@/lib/mongodb/connectDB"; import ProposalModel from "@/lib/mongodb/proposalSchema"; import { NextResponse } from "next/server"; export async function POST(request: Request) { try { await connectDB(); const { proposalId, newComment } = await request.json(); const result = await ProposalModel.findOneAndUpdate( { proposalId }, { $set: { comment: newComment } }, { new: true } ); if (!result) { return NextResponse.json({ error: "Proposal not found" }, { status: 404 }); } return NextResponse.json({ success: true, data: result }); } catch (error) { return NextResponse.json({ error: (error as Error).message }, { status: 500 }); } }
步骤2:修改前端调用逻辑
const [comment, setComment] = useState(""); const handleSendTransaction = async () => { if (!comment.length) return; try { const res = await fetch("/api/add-comment", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ proposalId, newComment: comment }), }); if (!res.ok) throw new Error("Failed to add comment"); const data = await res.json(); console.log("Comment added:", data); } catch (err) { console.error("Error adding comment:", err); } };
3. 确保Model正确导出
检查Schema文件末尾是否正确导出ProposalModel:
// 在proposalSchema.ts末尾添加 export default ProposalModel;
关键原因说明
- Next.js客户端环境无法运行mongoose,必须通过服务端环境(API路由/Server Component)处理数据库操作。
- 原connectDB的连接状态判断逻辑存在漏洞,当无连接时
mongoose.connections为空数组,直接读取[0]会触发undefined错误。
内容的提问来源于stack exchange,提问作者rashmor
相关产品推荐
相关产品推荐

