无法使用getInitialProps连接到mongoDB数据库

wbrvyc0a  于 2022-12-18  发布在  Go
关注(0)|答案(1)|浏览(94)

我尝试在_app.js中使用getInitialProps连接到示例mongoDB集合,但是遇到了Module not found: Can't resolve 'dns'的问题
_app.js

import { connectToDatabase } from '../middlewares/mongodb';

function MyApp({ Component, pageProps, prop }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

MyApp.getInitialProps = async (appContext) => {
  const { db } = await connectToDatabase();
  const data = await db
    .collection('listingsAndReviews')
    .find({})
    .limit(10)
    .toArray();

  const prop = JSON.parse(JSON.stringify(data));
  return { ...prop };
};
huus2vyu

huus2vyu1#

getInitialProps在初始页面加载期间在服务器上运行,在客户端导航期间在客户端上运行。因此,getInitialProps应该包含同构代码-能够在服务器和客户端环境中运行的代码。
在您的示例中,您的代码需要Node.js环境(服务器),因此在浏览器上运行时会失败。
一个可能的解决方案是将数据库提取逻辑移到API路由。

// pages/api/listings

export const fetchDbData = async () => {
    const { db } = await connectToDatabase();
    const data = await db
        .collection('listingsAndReviews')
        .find({})
        .limit(10)
        .toArray();
    return JSON.parse(JSON.stringify(data));
}

export default async (req, res) => {
    const data = await fetchDbData()
    res.status(200).json(data)
}

getInitialProps中,当fetchDbData逻辑在服务器上运行时,您可以直接调用它;当fetchDbData逻辑在客户机上运行时,您可以进行API调用。

import { fetchDbData } from './api/listings';

MyApp.getInitialProps = async (appContext) => {
    let prop;

    if (appContext.ctx.req) { // Checks if running on server
        prop = await fetchDbData(); // Call logic directly on the server
    } else {
        const res = await fetch('/api/listings'); // Make API call on the client
        prop = await res.json();
    }

    return { ...prop };
};

这确保了数据库获取逻辑将始终在服务器环境中运行。

相关问题