我正在为我的妹妹建立一个网站,这样她就可以出售她的艺术品。我使用Next.js来设置一切。网站通过从数据库中获取一个数组并通过它进行Map来渲染艺术品。
两个示例对象
{
id: 8,
path: "images/IMG_0008.jpg",
size: "9x12x.75",
price: "55",
sold: false
}
{
id: 9,
path: "images/IMG_0009.jpg",
size: "9x12x.75",
price: "55",
sold: false
}
pages/Shop.js
import Card from "../Components/Card";
import fetch from 'node-fetch'
import Layout from "../components/Layout";
function createCard(work) {
return (
<Card
key={work.id}
id={work.id}
path={work.path}
size={work.size}
price={work.price}
sold={work.sold}
/>
);
}
export default function Shop({artwork}) {
return (
<Layout title="Shop">
<p>This is the Shop page</p>
{artwork.map(createCard)}
</Layout>
);
}
export async function getStaticProps() {
const res = await fetch('http://localhost:3000/api/get-artwork')
const artwork = await res.json()
return {
props: {
artwork,
},
}
}
我遇到的问题是,当我尝试在api/get-artwork中使用mongoose时,它只会呈现页面一次,一旦刷新,它就会中断,我相信这是因为架构和模型被重做了。
pages/api/获取图片.js/
const mongoose = require("mongoose");
mongoose.connect('mongodb://localhost:27017/ArtDB', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
});
const itemsSchema = {
id: String,
description: String,
path: String,
size: String,
price: Number,
sold: Boolean
};
const Art = mongoose.model("Art", itemsSchema);
export default (req, res) => {
Art.find({sold: false}, (err, foundItems)=> {
if (err) {
console.log(err);
} else {
console.log(foundItems);
res.status(200).json(foundItems);
}
});
};
所以为了解决这个问题,我决定使用原生的MongoDB驱动程序。就像这样。
/pages/api/获取图片/
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'ArtDB';
// Create a new MongoClient
const client = new MongoClient(url, {useUnifiedTopology: true});
let foundDocuments = ["Please Refresh"];
const findDocuments = function(db, callback) {
// Get the documents collection
const collection = db.collection('arts');
// Find some documents
collection.find({}).toArray(function(err, arts) {
assert.equal(err, null);
foundDocuments = arts;
callback(arts);
});
}
// Use connect method to connect to the Server
client.connect(function(err) {
assert.equal(null, err);
const db = client.db(dbName);
findDocuments(db, function() {
client.close();
});
});
export default (req, res) => {
res.send(foundDocuments);
};
这在大多数情况下都有效,但有时数组不会被返回。我想这是因为页面在mongodb部分完成之前加载了?所以我想我的问题是,我如何100%确保它每次都正确加载艺术作品,无论是使用mongoose还是本机驱动程序。
谢谢你!
5条答案
按热度按时间20jt8wwn1#
Next.js团队有一组很好的示例代码,他们定期添加这些代码,其中之一是带有MongoDB和Mongoose的Next.js。如果您还在寻找解决方案,请查看https://github.com/vercel/next.js/tree/canary/examples/with-mongodb-mongoose,希望这对您有所帮助。
eulz3vhy2#
一个更完整的答案可能会有帮助。
我会建议使用next-connect库来使这变得简单一点,而不是那么多余。
注意到开发中不必要的重新连接,所以我绑定到节点中的全局this属性。也许这不是必需的,但这就是我注意到的。可能在开发过程中绑定到热重载。
这是一个很长的帖子,但并不像看起来那么复杂,如果你有问题,请评论。
创建中间件帮助程序:
创建模型:
通常,此处的路径可能是
src/models/app.ts
。实施下一个连接:
通常,我会将它放在
src/middleware/index.ts
这样的路径中(如果不使用Typescript,则放在index.js中)。注意:这里的
...middleware
只允许您(见下文)在创建这里的处理程序时动态传入其他中间件。这是非常有用的,因为我们的处理程序创建器可以有日志和其他有用的中间件,所以它在每个页面/api文件中不是那么多余。
用于Api途径:
把这些放在一起,我们现在可以轻松地使用我们的应用程序模型
sirbozc53#
在**页/api/get-artwork.js/**中
对我来说很好。
31moq8wy4#
当我们在
express.js
中使用mongoose时,我们连接到mongodb并运行一次代码,但在next.js中,每次需要连接到mongodb时,我们都必须运行连接代码。连接到mongodb
在下一个API中使用它
在运行处理程序代码之前,需要先连接
vwkv1x7d5#
简洁的OO方法
受@Blujedis答案的启发,这就是我最终得到的答案。
示例处理程序: