【问题标题】:How to get param from url in getStaticProps without using getStaticPaths?如何在不使用 getStaticPaths 的情况下从 getStaticProps 中的 url 获取参数?
【发布时间】:2021-04-08 00:57:30
【问题描述】:

下面是我的函数,其中我使用 getServerSideProps() 方法并根据我的 URL 中的参数 post_slug 动态获取数据。

// This gets called on every request
export async function getServerSideProps({ query }) {
  const { post_slug } = query || {};

  let url = API_URLS.POST.GET_POST_BY_SLUG;

  url = url.replace(/#POST_SLUG#/g, post_slug);

  const res = await fetch(url);
  const { data } = (await res.json()) || {};

  // Pass post_data to the page via props
  return { props: { data } };
}

但是这个函数在每次请求时都会渲染一个完整的页面。

所以现在我决定使用 getStaticProps() 但在这里我无法从 URL 获取参数 post_slug。

我阅读了next js 文档,他们告诉我需要使用 getStaticPaths() 和 getStaticProps() 方法,但这里的问题是我必须在 getStaticPaths() 方法中定义静态参数,但我想要来自当前 URL 的参数。

有没有办法在getStaticProps()方法中从URL获取param post_slug?

【问题讨论】:

    标签: reactjs next.js


    【解决方案1】:

    您可以使用getStaticPathsfallback 设置为true 来获取参数(不是查询)并在请求时创建静态页面。

    在这种情况下,当访问者访问在构建时尚未生成的路径时,Next.js 将在对此类路径的第一次请求时提供页面的“回退”版本(可以简单地为 <div>Loading...</div>

    Next.js 将运行 getStaticProps 并首次构建页面和数据 json 并在准备好后提供给访问者。

    Next.js 还会将此路径添加到预渲染页面列表中,因此对同一路径的后续请求将服务于生成的页面,就像在构建时预渲染的其他页面一样。

    在您的情况下,您不能简单地将getServerSideProps 替换为getStaticPaths。您必须创建一个[postSlug].js 才能使用参数postSlug

    // Example code
    import { useRouter } from 'next/router';
    
    function Post({ post }) {
      const router = useRouter();
      if (router.isFallback)  return <div>Loading...</div>;
      // Render post...
    }
    
    export async function getStaticPaths() {
      return {
        paths: [{ params: { postSlug: 'sth' } }, { params: { postSlug: 'sth-else' } }],
        fallback: true,
      };
    }
    
    export async function getStaticProps({ params }) {
      const res = await fetch(`https://.../posts/${params.postSlug}`);
      const post = await res.json();
      return {
        props: { post },
      }
    }
    
    export default Post;
    

    要更新静态生成的页面,请查看Next.js Incremental Static Regeneration

    【讨论】:

    • 您必须将每个可能的 URL 添加到 getStaticPaths 不是一个问题吗?在这种情况下postSlug。如果你有数百或数千呢?
    • 通常,您将从数据库中获取它们,例如const postSlugs = await Post.findMany(),然后将结果映射到`paths。
    • 嗨,我可以得到这个线程的支持吗? stackoverflow.com/questions/67591370/…
    【解决方案2】:

    您不能。
    getStaticProps 将在构建时获取数据,您将无法使用仅在请求期间可用的数据,例如查询参数或 HTTP 标头。
    如果您的页面显示经常更新的数据和/或动态内容,您应该改用服务器端渲染
    这实际上取决于您需要预渲染什么,请记住您仍然可以使用Router 并获取componentDidMountuseEffect 中的数据

    【讨论】:

      【解决方案3】:
      export async function getStaticPaths() {
        return {
          paths: [],
          // Enable statically generating additional pages
          // For example: `/posts/3`
          fallback: true,
        }
      }
      

      此信息已在文档link 中提及。

      引用文档:

      fallback: true 如果你的应用有大量的静态元素很有用 依赖数据的页面(想想:一个非常大的电子商务网站)。你 想要预渲染所有产品页面,但是你的构建需要 永远。

      相反,您可以静态生成一小部分页面并使用 后备:其余的都是真的。当有人请求的页面不是 尚未生成,用户将看到带有加载指示器的页面。 不久之后,getStaticProps 完成,页面将被渲染 与请求的数据。从现在开始,所有要求相同的人 page 将获得静态预渲染的页面。

      这可确保用户始终获得快速体验,同时保留 快速构建和静态生成的好处。

      如果您不想显示加载器状态,而是想显示浏览器请求页面(仅限第一次,将添加到预先生成的页面中以进行连续请求。)fallback:"blocking"

      对于开发,getStaticPaths 和 getStaticProps 将在每个请求上调用。

      【讨论】:

        【解决方案4】:

        使用getServerSidePropsgetStaticPathsgetStaticProps 用于生成要预渲染的静态页面。假设您在数据库中有博客,您获取博客、获取路径并将它们传递给 getStaticProps

        在您的情况下,context 对象被传递给getServerSideProps,您可以按如下方式访问 params.id:

        export const getServerSideProps = async (context) => {
          return { props: { paramsId: context.params.id } };
        };
        

        现在,当您提出请求时,next.js 会将“paramsId”传递给客户端,您可以使用props.paramsId 在组件内部访问它

        【讨论】:

        猜你喜欢
        • 2021-05-22
        • 1970-01-01
        • 2021-07-10
        • 2021-01-07
        • 2021-03-30
        • 2018-06-28
        • 2022-12-03
        • 2022-11-15
        • 2019-09-26
        相关资源
        最近更新 更多