如何避免在 Next.js v13 中两次获取相同的数据?

Luc*_*gan 5 typescript next.js next.js13

我需要从数据库中查找条目并生成元数据并呈现实际的页面内容。

目前,我正在这样做:

export const generateMetadata = async ({
  params: { questionSlug },
}: Props): Promise<Metadata> => {
  const sql = await connectToPostgres();

  const question = await findQuestion(sql, questionSlug);

  if (!question) {
    return {};
  }

  return {
    alternates: {
      canonical: `https://ray.run/questions/${question.slug}`,
    },
    title: question.question,
  };
};

const Page = async ({ params: { questionSlug } }: Props) => {
  const sql = await connectToPostgres();

  const question = await findQuestion(sql, questionSlug);

  if (!question) {
    return notFound();
  }

  // ...
};
Run Code Online (Sandbox Code Playgroud)

但这意味着我必须对相同的数据库查询两次才能呈现相同的页面。

有没有办法一次获取数据并在两种方法中使用它?

Luc*_*gan 5

这并不漂亮。然而,官方的方法是使用该cache函数

import { cache } from 'react';

const findQuestionWithCache = cache(async (questionSlug: string) => {
  const sql = await connectToPostgres();

  return await findQuestion(sql, questionSlug);
});

export const generateMetadata = async ({
  params: { questionSlug },
}: Props): Promise<Metadata> => {
  const question = await findQuestionWithCache(questionSlug);

  if (!question) {
    return notFound();
  }

  return {
    alternates: {
      canonical: `https://ray.run/questions/${question.slug}`,
    },
    title: question.question,
  };
};

const Page = async ({ params: { questionSlug } }: Props) => {
  const question = await findQuestionWithCache(questionSlug);

  if (!question) {
    return notFound();
  }

  // ...
};
Run Code Online (Sandbox Code Playgroud)

findQuestionWithCache每个请求只会调用该函数的内容一次。

遗憾的是,这种方法的缺点是cache无法在 React/Next.js 之外调用包装函数。因此,如果您在 React.js 代码库之外使用相同的函数,则必须像我在上面的示例中那样在本地包装它。如果您仅在 React.js 代码库中调用此函数,那么您可能只需包装原始实现即可。


小智 0

Next.js 对generateMetadata 的提取请求进行重复数据删除,但我不确定您的数据库连接。很高兴知道部分